题目来源:http://acm.pku.edu.cn/JudgeOnline/problem?id=2524
解题报告:
简单的并查集的应用吧
方法一:
#include <iostream> using namespace std; typedef struct _node { _node* parent; int rank; }node; node **s; void makeSet(int x) { s[x]=new node; s[x]->rank=0; s[x]->parent=s[x]; } node* findSet(node* s) { if(s!=s->parent) { s->parent=findSet(s->parent); } return s->parent; } void link(node *s1, node *s2) { if(s1==s2) return; if(s1->rank > s2->rank) s2->parent=s1; else { s1->parent=s2; if(s1->rank==s2->rank) s2->rank++; } } void _union(node *s1, node *s2) { link(findSet(s1),findSet(s2)); } int main() { int n; int m; scanf("%d %d",&n,&m); s=new node*[n]; int casenum=1; while(!(m==0 && n==0)) { s=new node*[n]; for(int i=0;i<n;i++) makeSet(i); while(m--) { int x,y; scanf("%d %d",&x,&y); _union(s[x-1],s[y-1]); } int cnt=0; for(int i=0;i<n;i++) { if(s[i]->parent==s[i]) cnt++; } cout << "Case " << casenum << ": " << cnt << endl; casenum++; scanf("%d %d",&n,&m); delete [] s; } return 0; }
思路二: 简化了上面的部分
#include <iostream> using namespace std; int p[50001]; int rank[50001]; void makeSet(int i) { p[i]=i; rank[i]=1; } int findSet(int x) { if(p[x]!=x) { p[x]=findSet(p[x]); } return p[x]; } void link(int x,int y) { if(rank[x] < rank[y]) p[x]=y; else { p[y]=x; if(rank[x]==rank[y]) rank[x]++; } } void _union(int x,int y) { link(findSet(x),findSet(y)); } int main() { int n; int m; scanf("%d %d",&n,&m); int casenum=1; while(!(m==0 && n==0)) { for(int i=0;i<n;i++) makeSet(i); while(m--) { int x,y; scanf("%d %d",&x,&y); _union(x-1,y-1); } int cnt=0; for(int i=0;i<n;i++) { if(p[i]==i) cnt++; } cout << "Case " << casenum << ": " << cnt << endl; casenum++; scanf("%d %d",&n,&m); } return 0; }
附录:
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 12171 | Accepted: 5759 |
Description
Input
Output
Sample Input
10 9 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 10 4 2 3 4 5 4 8 5 8 0 0
Sample Output
Case 1: 1 Case 2: 7
Hint