首页 > 其他 > 详细

【NOI2001】食物链

时间:2019-05-03 00:08:26      阅读:219      评论:0      收藏:0      [点我收藏+]

一道“扩展域”并查集的题目,我们把每一个点拆分成三个域:同类、食物、天敌。

我们假设x的同类域为x,食物域为x+n,天敌域为x+n+n。假设x与y是同类,那么说明x+n与y+n是同类,x+n+n与y+n+n是同类。

假设x吃y,那么x+n与y是同类,x+n+n与y+n是同类,x与y+n+n是同类。

现在我们只需要判断一句话与之前处理的关系是否冲突即可,如果不冲突,就按照上面的同类关系合并即可;冲突则统计答案。

技术分享图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 int n,m;
 6 int f[50010*3];
 7 int find(int x) {
 8     if(f[x]!=x) f[x]=find(f[x]);
 9     return f[x];
10 }
11 void add(int x,int y) {
12     f[find(x)]=find(y);
13 }
14 int main() {
15     cin>>n>>m;
16     for(int i=1;i<=n*3;i++) f[i]=i;
17     int ans=0;
18     for(int i=1;i<=m;i++) {
19         int op,x,y;
20         cin>>op>>x>>y;
21         if(x>n||y>n) {
22             ans++;
23             continue ;
24         }
25         if(op==1) {
26             if(find(x)==find(y+n)||find(x)==find(y+n+n)) ans++;
27             else {
28                 add(x,y);
29                 add(x+n,y+n);
30                 add(x+n+n,y+n+n);
31             }
32         }
33         else if(op==2) {
34             if(find(x)==find(y)||find(x)==find(y+n)) ans++;
35             else {
36                 add(x,y+n+n);
37                 add(x+n,y);
38                 add(x+n+n,y+n);
39             }
40         }
41     }
42     cout<<ans<<endl;
43     return 0;
44 }
AC Code

 

【NOI2001】食物链

原文:https://www.cnblogs.com/shl-blog/p/10803795.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!