http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1689
联盟 Time Limit:1000MS Memory Limit:32768K Description: 某大陆上有n个独立的国家,它们没有组成任何联盟。但从某一天开始,1号国家将某国拉拢过去作为联盟,然后2号国家也拉拢某国,然后3号。。。。一直到n号国家。如果拉拢的国家已有联盟,则将它所属联盟一起拉拢过来,形成新的联盟。当n次拉拢结束之后,求1号国家的联盟国有几个。 Input: 有多组测试数据。每组数据有两行,第一行为n(1<=n<=350000),第二行有n个数,分别表示n个国家拉拢的对象。 Output: 对每组数据输出1号国的联盟国有几个。 Sample Input: 3 3 3 1 3 2 1 2 Sample Output: 2 2 #include<stdio.h> #include<string> #include<iostream> #include<sstream> #include<algorithm> #include<vector> int fa[350001]; int find(int x) { int r=x; while(fa[r]!=r)r=fa[r]; int i=x; int j; while(i!=r) { j=fa[i]; fa[i]=r; i=j; } return r; } void join(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) { if(fx==1){fa[fy]=1; return;} if(fy==1){fa[fx]=1;return;} else fa[fx]=fy; } } using namespace std; int main() { int n,m; while(scanf("%d",&n)==1) { for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=n;i++) { scanf("%d",&m); join(i,m); } int sum=0; for(int i=2;i<=n;i++) { if(find(i)==1)sum++; } printf("%d\n",sum); } }