1、hihocoder上面讲的一道题
无间道之并查集
水题,精髓在于使用map容器进行打标签
#include <cstdio> #include <cstring> #include <iostream> #include <string> #include <map> #include <algorithm> using namespace std; const int maxn=10005; int p[maxn]; map<string,int> M; int m; int Find(int x) { return x == p[x] ? x : p[x]=Find(p[x]); } //打标签 int readln() { string str; cin>>str; if (M.count(str)) return M[str]; else M[str]=++m; p[m]=m; return m; } int main() { int n,relation; scanf("%d",&n); m=0; memset(p,0,sizeof(p)); for (int i=0;i<n;i++) { scanf("%d",&relation); int x=Find(readln()); int y=Find(readln()); if (relation & 1) { if (x == y) printf("yes\n"); else printf("no\n"); } else p[y]=x; } return 0; }
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn=50002; int p[maxn],Rank[maxn]; int ans; void init(int i) { p[i]=i; Rank[i]=0; } int Find(int x) { return x != p[x] ? p[x]=Find(p[x]) : x; } void union_set(int x,int y) { x=Find(x); y=Find(y); if (x == y) return; ans--;//精髓所在 if (Rank[x] > Rank[y]) { p[y]=x; } else { p[x]=y; if (Rank[x] == Rank[y]) Rank[y]++; } } int main() { int n,m; int j=0; while (scanf("%d%d",&n,&m)) { if (n == 0 && m == 0) break; ans=n; for (int i=1;i<=n;i++) init(i); int x,y; for (int i=0;i<m;i++) { scanf("%d%d",&x,&y); union_set(x,y); } printf("Case %d: %d\n",++j,ans); } return 0; }
3、POJ1611
加一个Rank[],表示每个数的等级,高的相对于为父节点
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 30001; int p[maxn],num[maxn],Rank[maxn]; void init(int i) { p[i]=i; num[i]=1; Rank[i]=0; } int Find(int x) { return x!=p[x] ? p[x]=Find(p[x]) : x; } void union_set(int i,int j) { int x=Find(i); int y=Find(j); if (x == y) return; if (Rank[x] > Rank[y]) { p[y]=x; num[x]+=num[y]; } else { p[x]=y; if (Rank[x] == Rank[y]) Rank[y]++; num[y]+=num[x]; } } int main() { int n,m; while (scanf("%d%d",&n,&m)) { if (n == 0 && m == 0) break; if (m == 0) { printf("1\n"); continue; } for (int i=0;i<n;i++) init(i); while (m--) { int k,x,y; scanf("%d",&k); scanf("%d",&x); for (int i=1;i<k;i++) { scanf("%d",&y); union_set(x,y); x=y; } } int ans=Find(0); printf("%d\n",num[ans]); } return 0; }