kuangbin专题五:并查集
作者:互联网
不想写实验,不想改paper,写点代码吧(;´д`)ゞ
思路:简单并查集。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 1e3 + 5; int N, D; int p[maxn]; bool vis[maxn]; struct Pos{ int x, y; }pos[maxn]; int findP(int x){ return x == p[x] ? x : p[x] = findP(p[x]); } void Union(int x, int y){ int px = findP(x), py = findP(y); if(px != py) p[px] = py; } bool in_dis(int x, int y){ int dx = pos[x].x - pos[y].x; int dy = pos[x].y - pos[y].y; return dx*dx + dy*dy <= D*D; } void repair(int x){ for(int i = 1; i <= N; i++) if(vis[i] && in_dis(i, x)) Union(i, x); vis[x] = true; } int main(){ cin >> N >> D; for(int i = 1; i <= N; i++) p[i] = i; for(int i = 1; i <= N; i++) cin >> pos[i].x >> pos[i].y; char op; int u, v; while(cin >> op){ if(op == 'O'){ cin >> u; repair(u); } else{ cin >> u >> v; int pu = findP(u), pv = findP(v); cout << (pu == pv ? "SUCCESS" : "FAIL") << endl; } } return 0; }View Code
思路:简单并查集。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 3e4 + 5; const int maxm = 505; int p[maxn]; inline int findP(int x){ return x == p[x] ? x : p[x] = findP(p[x]); } inline void Union(int x, int y){ int px = findP(x), py = findP(y); if(px != py) p[px] = py; } int main(){ int n, m; while(cin >> n >> m && (n + m > 0)){ for(int i = 0; i < n; i++) p[i] = i; int k, s1, s2; for(int i = 1; i <= m; i++){ cin >> k; if(k) cin >> s1; for(int j = 1; j < k; j++){ cin >> s2; Union(s1, s2); } } int res = 0; for(int i = 0; i < n; i++) if(findP(0) == findP(i)) res++; cout << res << endl; } return 0; }View Code
思路:简单并查集。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 1e3 + 5; const int maxm = 1e3 + 5; int p[maxn]; bool vis[maxn]; inline int findP(int x){ return x == p[x] ? x : p[x] = findP(p[x]); } inline void Union(int x, int y){ int px = findP(x), py = findP(y); if(px != py) p[px] = py; } int main(){ int T; cin >> T; while(T--){ int n, m; cin >> n >> m; for(int i = 1; i <= n; i++) p[i] = i; memset(vis, 0, sizeof(vis)); for(int i = 1; i <= m; i++){ int x, y; cin >> x >> y; Union(x, y); } int res = 0; for(int i = 1; i <= n; i++){ int pi = findP(i); if(!vis[pi]){ vis[pi] = true; res++; } } cout << res << endl; } return 0; }View Code
HDU3038 How Many Answers Are Wrong
思路:带权并查集。这题个人觉得模型比较难想到,我第一次接触到的时候被提醒了才想起来带权并查集。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 2e5 + 5; int p[maxn], w[maxn]; int findP(int x){ if(x != p[x]){ int px = p[x]; p[x] = findP(p[x]); w[x] += w[px]; } return p[x]; } int main(){ int n, m; while(scanf("%d%d", &n, &m) != EOF){ for(int i = 0; i <= n; i++) p[i] = i, w[i] = 0; int res = 0; while(m--){ int a, b, s; scanf("%d%d%d", &a, &b, &s); a--; int pa = findP(a), pb = findP(b); if(pa == pb){ if((w[a] - w[b]) != s) res++; } else{ p[pa] = pb; w[pa] = w[b] - w[a] + s; } } cout << res << endl; } return 0; }View Code
思路:经典带权并查集问题了。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 5e4 + 5; int p[maxn], w[maxn]; int findP(int x){ if(x != p[x]){ int px = p[x]; p[x] = findP(p[x]); w[x] = (w[x] + w[px]) % 3; } return p[x]; } int main(){ int n, m; scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) p[i] = i, w[i] = 0; int res = 0; while(m--){ int d, x, y; scanf("%d%d%d", &d, &x, &y); if (x > n || y > n) { res++; continue; } if (d == 2 && x == y) { res++; continue; } d--; int px = findP(x), py = findP(y); if (px == py && (w[y] - w[x] + 3) % 3 != d){ res++; } else { p[py] = px; w[py] = (w[x] + d - w[y] + 3) % 3; } } cout << res << endl; return 0; }View Code
思路:
标签:专题,int,px,查集,maxn,kuangbin,py,include,findP 来源: https://www.cnblogs.com/arch/p/14352743.html