您的位置:首页 > 其它

N - Is It A Tree? POJ - 1308

2018-01-16 11:53 330 查看
题意:给你一个图问你是不是一棵树,输入很叽歪。。。

思路:如何判断一个图是不是树,那就是只有一个根节点,而且没有环对吧,这道题其实就是并查集的一个更加深层次的运用了,我们想一下原来我们怎样判断一个图里有没有环?我们只能深搜,从一个点枚举他可以到达的所有点,看他之后能不能又回到他本身对吧,这种时间复杂度简直爆炸。。而并查集就可以超级超级完美的解决这个问题了,想想如果a和b本身就在一棵树上了,那么在往a和b上连一条边,那么必定会变成一个环,因为a永远可以通过根节点到达b对吧,所以如果看两个数a,b在一个集合里那么他就肯定是一个环,还有一些小细节在里面代码上有:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 1e5+10;
int p[maxn] , vis[maxn];
int getf(int x)
{
return x == p[x] ? x : p[x] = getf(p[x]);
}
void init()
{
for(int i = 0 ; i <= maxn ; i++)
{
p[i] = i;
vis[i] = 0;
}
}
int main()
{
int a,b;
int cnt = 0 ,flag = 0 ;
init();
while(scanf("%d%d",&a,&b)!=EOF)
{
if(a == -1 && b == -1) break;
if(a == 0 && b == 0 )
{
int cur = 0 ;
if(flag) printf("Case %d is not a tree.\n",++cnt);
else
{
for(int i = 1 ; i <= maxn ; i++)
{
if(vis[i]) //当这个点用过了我们才判断
if(p[i]==i) cur++;
}
if(cur == 1 || cur ==0) printf("Case %d is a tree.\n",++cnt);//这里如果把0去掉就会wa,我自己就wa了好多次
else printf("Case %d is not a tree.\n",++cnt);
}
flag = 0 ;
init();
}
else
{
vis[a] = 1,vis[b] = 1;
int ta = getf(a),tb = getf(b);
if(ta != tb)
{
p[ta] = tb;
}
else
{
flag = 1;
}
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: