题目大意:先输入n,表示节点个数,开始每个节点是孤立的,输入I a b表示在a和b之间建立连接,C a b表示检查a与b是否联通(联通输出"yes",不能联通输出"no"),S表示输入结束并输出整个网络的联通情况(联通了输出“The network is connected.”,未联通输出“There are k components.”, k表示孤立的网络数量)
思路:考察并查集,用N[I]表示节点i的父节点,使用路径压缩(使用递归很巧妙的给出每个节点i的最终父节点N[i],N[i] = -1表示无父节点)
代码:
/*
*考察并查集
*/
#include<stdio.h>
int N[10001];
int findRoot(int N[],int x)
{
if(N[x] < 0)
return x;
else
{
return N[x] = findRoot(N,N[x]);
}
}
void Input_Connection()
{
int a,b;
scanf("%d%d",&a,&b);
int root1,root2;
root1 = findRoot(N,a);
root2 = findRoot(N,b);
if(root1 != root2)
{
N[root1] = root2;
}
}
void Check_Connection(char ch,int n)
{
int count = 0;
if(ch == 'C')
{
int a,b;
scanf("%d%d",&a,&b);
if(findRoot(N,a) != findRoot(N,b))
printf("%s\n","no");
else
printf("%s\n","yes");
}
if(ch == 'S')
{
for(int i = 1; i <= n; i++)
{
if(N[i] == -1)
count++;
}
if(count == 1)
printf("%s","The network is connected.\n");
else
printf("There are %d components.\n",count);
}
}
int main()
{
int n,i;
char ch;
scanf("%d",&n);
getchar(); //吃掉空格
for(i = 1; i <= n; i++)
{
N[i] = -1;
}
do
{
scanf("%c",&ch);
switch(ch)
{
case 'I':
Input_Connection();
break;
case 'C':
Check_Connection(ch,n);
break;
case 'S':
Check_Connection(ch,n);
break;
}
}while(ch != 'S');
return 0;
}