简单模板
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<map> using namespace std; //hdu 1213 int node[1000+10]; int Find(int x) { if(node[x] == x) return x; //压缩 int root = Find(node[x]); node[x] = root; return root; } int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) node[i] = i; for(int i=0;i<m;++i) { int a,b,x,y; scanf("%d%d",&a,&b); x = Find(a); y = Find(b); if(x != y) { node[x] = y; } } map<int,int> mii; int cnt = 0; for(int i=1;i<=n;++i) { int root = Find(i); pair<map<int,int>::iterator,bool> pmb = mii.insert(pair<int,int>(root,0)); if(pmb.second) ++cnt; } printf("%d\n",cnt); } return 0; } /* 100 3 2 1 2 2 1 */
简单模板
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; int node[1000+10]; int Find(int x) { if(node[x] == x) return x; int root = Find(node[x]); node[x] = root; return root; } int main() { int n,m; while(~scanf("%d",&n),n) { scanf("%d",&m); for(int i=1;i<=n;++i) node[i] = i; for(int i=0;i<m;++i) { int a,b,x,y; scanf("%d%d",&a,&b); x = Find(a); y = Find(b); if(x != y) node[x] = y; } int cnt = 0; for(int i=1;i<=n;++i) if(node[i] == i) ++cnt; printf("%d\n",cnt-1); } return 0; }
判断是否有环。该题只输入0 0,要求输出Yes
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int node[100000+10]; int vis[100000+10]; int flag = 0; //是否有环 int Find(int x) { if(node[x] == x) return x; int y = Find(node[x]); node[x] = y; return y; } void Union(int a,int b) { if(a == b) return; int x = Find(a); int y = Find(b); if(x == y) flag = 1; else{node[x] = y;} } int main() { int a,b; while(true) { for(int i=0;i<=100000+10;++i) node[i] = i; memset(vis,0,sizeof(vis)); flag = 0; while(~scanf("%d%d",&a,&b)) { if(a==0 && b==0) break; if(a==-1 && b==-1) break; if(!vis[a]){vis[a]=1;} if(!vis[b]){vis[b]=1;} Union(a,b); } if(a==-1 && b==-1) break; int p = 0; //确保只有一个连通图,p==1 for(int i=1;i<100000+10;++i) if(vis[i]&&i == Find(i)) ++p; if(!flag && p<=1) printf("Yes\n"); else printf("No\n"); } return 0; }
跟1272类似,但是退出条件为小于0,小于0.并且在原有无环的判断条件后,增加了根的入度为0,节点的入度为1,才能会树。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define N (10000+10) int node[N]; int vis[N]; int indegree[N]; int tp; int flag; int Find(int x) { if(node[x] == x) return x; int y = Find(node[x]); node[x] = y; return y; } void Union(int a,int b) { if(a==b){flag = 1;return;} int x = Find(a); int y = Find(b); if(x==y) flag = 1; else node[x] = y; } int main() { int t=0; while(true) { int a,b; for(int i=0;i<N;++i) node[i] = i; memset(vis,0,sizeof(vis)); memset(indegree,0,sizeof(indegree)); tp = 0; flag = 0; while(~scanf("%d%d",&a,&b)) { if(a==0&&b==0) break; if(a<0&&b<0) break; vis[a] = 1; vis[b] = 1; ++indegree[b]; Union(b,a); } if(a<0&&b<0) break; for(int i=0;i<N;++i) { if(!vis[i]) continue; if(i == Find(i)) ++tp; if(i == Find(i) && indegree[i]!=0) flag = 1; if(i != Find(i) && indegree[i]!=1) flag = 1; //if(i == Find(i)) printf("test %d\n",i); //if(i == Find(i)){printf("i=%d,indegree=%d\n",i,indegree[i]);} } printf("Case %d ",++t); if(!flag && tp <= 1) printf("is a tree.\n"); else printf("is not a tree.\n"); } return 0; }
当n等于0的时候,输出为1,虽然数组要10的七次方,但是仍可以用1325的方法解。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define N (10000000+10) int node[N]; int cnt[N]; int Find(int x) { if(node[x]==x) return x; int y = Find(node[x]); node[x] = y; return y; } void Union(int a,int b) { if(a==b) return; int x = Find(node[a]); int y = Find(node[b]); if(x!=y) { node[x] = y; } } int main() { int n; while(~scanf("%d",&n)) { for(int i=0;i<N;++i) node[i] = i,cnt[i] = 0; for(int i=0;i<n;++i) { int a,b; scanf("%d%d",&a,&b); Union(a,b); } int MaxCnt = 1; for(int i=0;i<N;++i) { int y = Find(i); ++cnt[y]; MaxCnt = MaxCnt > cnt[y] ? MaxCnt : cnt[y]; } printf("%d\n",MaxCnt); } return 0; }