下面我们来看并查集的实现。 int pre[1000]; 这个数组,记录了每个大侠的上级是谁。大侠们从1或者0开始编号(依据题意而定),pre[15]=3就表示15号大侠的上级是3号大侠。如果一个人的上级就是他自己,那说明他就是掌门人了,查找到此为止。也有孤家寡人自成一派的,比如欧阳锋,那么他的上级就是他自己。每个人都只认自己的上级。比如胡青牛同学只知道自己的上级是杨左使。张无忌是谁?不认识!要想知道自己的掌门是谁,只能一级级查上去。 getf这个函数就是找掌门用的,意义再清楚不过了(路径压缩算法先不论,后面再说)。
1 2 3 4 5 6 7
int getf(int a)//查找根节点 { if (pre[a] == a)//我的上级不是掌门 return a; int tmp = getf(pre[a]);//我就找他的上级,直到掌门出现 return pre[a] = tmp;//掌门出现 }
#include <bits/stdc++.h> typedef long long ll; const int maxx = 10010; const int inf = 0x3f3f3f3f; using namespace std; int pre[maxx]; int n, m, ans; void init() { for (int i = 0; i <= n; i++) pre[i] = i; } int getf(int a) { if (a == pre[a]) return a; return pre[a] = getf(pre[a]); } int mer(int a, int b) { int fa = getf(a); int fb = getf(b); if (fa != fb) { pre[fa] = fb; ans--; } } int main() { while (~scanf("%d%d", &n, &m), n) { init(); int a, b; ans = n - 1; for (int i = 0; i < m; i++) { scanf("%d%d", &a, &b); mer(a, b); } printf("%d\n", ans); } return 0; }
#include <bits/stdc++.h> typedef long long ll; const int maxx = 100010; const int inf = 0x3f3f3f3f; using namespace std; int pre[maxx], v[maxx]; int n, m, q; int x, y, s; int ans; void init() { for (int i = 0; i <= n; i++) { pre[i] = i; v[i] = 0; } } int getf(int a) { if (pre[a] == a) return a; int tmp = getf(pre[a]); v[a] = v[a] + v[pre[a]]; return pre[a] = tmp; } void mer(int a, int b, int s) { int fa = getf(a); int fb = getf(b); if (fa != fb) { pre[fa] = fb; v[fa] = -v[a] + s + v[b]; } } template <class T> inline void read(T &res) //快速读入模板 { char c; T flag = 1; while ((c = getchar()) < '0' || c > '9') if (c == '-') flag = -1; res = c - '0'; while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0'; res *= flag; } int main() { read(n), read(m), read(q); init(); while (m--) { read(x), read(y), read(s); mer(x, y, s); } while (q--) { read(x), read(y); if (getf(x) == getf(y)) printf("%d\n", v[x] - v[y]); else printf("-1\n"); } return 0; }
#include <bits/stdc++.h> typedef long long ll; const int maxx = 200010; const int inf = 0x3f3f3f3f; using namespace std; int pre[maxx], v[maxx]; int n, m; int x, y, s; void init() { for (int i = 0; i <= n; i++) { pre[i] = i; v[i] = 0; } } int getf(int a) { if (pre[a] == a) return a; int tmp = getf(pre[a]); v[a] = v[a] + v[pre[a]]; return pre[a] = tmp; } int mer(int a, int b, int s) { int fa = getf(a); int fb = getf(b); if (fa == fb) return v[a] != v[b] + s; else { pre[fa] = fb; v[fa] = -v[a] + v[b] + s; return 0; } } int main() { while (~scanf("%d%d", &n, &m)) { init(); int ans = 0; while (m--) { scanf("%d%d%d", &x, &y, &s); y++; if (mer(x, y, s)) ans++; } printf("%d\n", ans); } return 0; }
#include <stdio.h> #include <string> #include <string.h> #include <algorithm> #include <iostream> #include <math.h> #include <queue> #include <stack> #include <vector> #include <map> typedef long long ll; const int maxx = 100010; const int inf = 0x3f3f3f3f; using namespace std; int pre[maxx * 2]; int n, m; void init() { for (int i = 0; i <= 2 * n; i++) { pre[i] = i; } } int getf(int a) { if (pre[a] == a) return a; int tmp = getf(pre[a]); return pre[a] = tmp; } void mer(int a, int b) { int fa = getf(a); int fb = getf(b); if (fa != fb) pre[fa] = fb; } int same(int a, int b) { return getf(a) == getf(b); } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); init(); char s; int a, b; while (m--) { getchar(); scanf("%c%d%d", &s, &a, &b); if (s == 'D') { mer(a, b + n); mer(b, a + n); } else { if (same(a, b)) { printf("In the same gang.\n"); continue; } else if (same(a, b + n)) { printf("In different gangs.\n"); } else { printf("Not sure yet.\n"); } } } } return 0; }