带权并查集 —— POJ1182 食物链(转载)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <queue> 5 #include <vector> 6 #include <cmath> 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 }
1