杭电acm 1213 (How many tables)

 

//思路:把所有认识的朋友组成一棵树,只要知道有几棵树,就知道需要几张桌子了。(这里的树为了方便查找根,将子节点指向根节点) 初始化时将所有树的根设为-1;
//通过依次读入认识的朋友(a,b),利用find查找当前朋友(a)的上级节点,然后利用connect将上级节点和b连通。即(friends[find(a)]=b)。(如果没有上及节点(即friends[a]=-1),则直接friends[a]=b)
//最后遍历所有人,将根放入set容器中,输出容器的大小即为桌子数量。
#include<iostream>
#include<set>
using namespace std;
int friends[1001];
int find(int i)//递归查找当前节点的上级节点如果friends[i]<0,当前节点即为最上级
{
	if(friends[i]>0)
	{
		i=friends[i];
		find(i);
	}
	else
	{
		return i;
	}

}
void connect(int n,int m)
{
	int x=find(n);
	int y=find(m);
	if(x!=y)  //如果已经链接过,就不在链接
	{
		friends[x]=y;
	}
}
int  searchroot(int n)
{
	set<int> tables;    //利用set容器内部能存放相同元素的特性,可以很容易知道当前哪些节点的根式相同的。
    for(int i=1;i<=n;i++)
		tables.insert(find(i));
	return tables.size();
}
int main()
{
	int T,n,m,a,b,count,i;
	cin>>T;
	while(T--)
	{
		cin>>n>>m;
		fill(friends,friends+n+1,-1);//前两个参数为地址。在此地址内填充-1.头文件iostream. 注意:要想填充到第n个数,必须为n+1。(最初在此出错,但我测试过如果不将此全局数组填充为-1,在vc6.0下默认是全部初始化为0的,按照这样应该不影响结果。估计HDOJ不是默认初始化。悲剧哈!)
	    for(i=0;i<m;i++)
		{
           cin>>a>>b;
		   connect(a,b);
		}
		cout<<searchroot(n)<<"\n";
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值