poj 1182 并查集(应用)

poj 1182 并查集(应用)
http://poj.org/problem?id=1182

维护每个孩子和父亲的关系,0=和父亲同类,1=可以吃父亲,2=可以被父亲吃.

整个题,只有一个主要集合,这个和其他并查集不一样有很多大小不同的集合,然后合并,这个题目是每次将一个未知的点插入到已知关系的集合中,并建立与父亲的关系,然后每次查找的路径压缩让两个节点可以通过父亲来判断他们的关系,比如 v[x]=1 v[y]=2 说明x吃了他父亲,y能被他父亲吃,所以y可以吃掉x,这样就能找到关系了,路径压缩的时候 要理解好递归的思路,每次通过自己的父亲算出与上一个父亲的关系,自己画一画然后思考.这次比较幸运,竟然能够一次AC,说明我的编码能力有提高. 说真的,结构体类,真的挺好玩的...构造函数可以写struct...

code:

 1 #include<iostream>
 2 #include<cstdio>
 3  using  namespace std;
 4  #define REP(i,from,to) for(int i=(from);i<=(to);++i)
 5  int a[50001];
 6  int v[50001];
 7  int n;
 8  struct disset{
 9      int *d;
10      int *v;
11      int l;
12     disset( int *_d, int *_v, int _l):d(_d),v(_v),l(_l){
13         REP(i,1,l){
14             a[i]=i;
15             v[i]=0;
16         }
17     }
18      int find( int x){
19          int u = d[x];
20          if(u!=x){
21             d[x] = find(u);
22             v[x] = (v[x]+v[u]) % 3;
23         }
24          return d[x];
25     }
26      void same( int x, int y){
27          int u = find(x);
28         d[u] = y;
29          if(v[x]==0)
30             v[u]=0;
31          else  if(v[x]==1)
32             v[u]=2;
33          else
34             v[u]=1;
35         
36     }
37      void eat( int x, int y){
38          int u = find(x);
39         d[u]=y;
40          if(v[x]==2)
41             v[u]=2;
42          else  if(v[x]==0)
43             v[u]=1;
44          else
45             v[u]=0;
46     }
47      bool is_eat( int x, int y){
48          if(v[x]==0 && v[y]==2 ||
49             v[x]==1 && v[y]==0 ||
50             v[x]==2 && v[y]==1)
51              return  true;
52          return  false;
53     }
54 };
55  struct disset *s;
56  bool sentence( int d, int x, int y){
57      if(x>n || y>n)
58          return  false;
59      if(d==1){
60          int ux = s->find(x);
61          int uy = s->find(y);
62          if(ux!=uy){
63             s->same(x,y);
64         }
65          else  if(v[x]!=v[y])
66              return  false;
67     }
68      else{
69          int ux = s->find(x);
70          int uy = s->find(y);
71          if(ux!=uy){
72             s->eat(x,y);
73         }
74          else  if(!s->is_eat(x,y))
75              return  false;
76     }
77      return  true;
78 }
79  int main(){
80      int ccase,ans=0;
81     scanf("%d%d",&n,&ccase);
82      // REP(i,1,5)
83       //     cout<<i<<"  |";
84       // cout<<endl;
85      s =  new  struct disset(a,v,n);
86      while(ccase--){
87          int d,x,y;
88         scanf("%d%d%d",&d,&x,&y);
89          if(!sentence(d,x,y))
90             ans++;
91 
92      //     REP(i,1,5)
93       //         cout<<a[i]<<' '<<v[i]<<'|';
94       //     cout<<endl;
95      }
96     printf("%d\n",ans);
97      return 0;
98 }

你可能感兴趣的:(poj 1182 并查集(应用))