带权并查集 —— POJ1182 食物链

传送门

 

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 
 8 using namespace std;
 9 
10 #define ll long long
11 #define pb push_back
12 #define fi first
13 #define se second
14 
15 const int N = 5e4 + 10;
16 struct node{
17     int rt, v;
18 }fa[N];
19 int n, m;
20 
21 int Find(int x)
22 {
23     if(fa[x].rt == x){
24         return x;
25     }else{
26         int tmp = fa[x].rt;
27         fa[x].rt = Find(fa[x].rt);
28         fa[x].v = (fa[x].v + fa[tmp].v) % 3;
29         return fa[x].rt;
30     }
31 }
32 
33 bool Union(int x, int y, int d)
34 {
35     int fax = Find(x);
36     int fay = Find(y);
37 
38     if(fax != fay){
39         fa[fay].rt = fax;
40         fa[fay].v = (fa[x].v + d - 1 - fa[y].v + 3) % 3;
41         return true;
42     }else{
43         if(d == 1 && fa[x].v == fa[y].v) return true;
44         else if(d == 2 && (0 - fa[x].v + fa[y].v + 3) % 3 == d - 1) return true;
45         else return false;
46     }
47 }
48 
49 void solve()
50 {   
51     scanf("%d%d", &n, &m);
52     int ans = 0;
53 
54     for(int i = 1; i <= n; ++i) fa[i].rt = i, fa[i].v = 0;
55     for(int i = 1; i <= m; ++i){
56         int d, x, y;
57         scanf("%d%d%d", &d, &x, &y);
58 
59         if(x > n || y > n || (d == 2 && x == y)) ans++;
60         else if(!Union(x, y, d)) ans++; 
61     } 
62     //printf("ans = %d\n", ans);
63     printf("%d\n", ans);
64 }
65 
66 int main()
67 {
68 
69     solve();
70 
71     return 0;
72 }

 

你可能感兴趣的:(带权并查集 —— POJ1182 食物链)