H - Is It A Tree? POJ - 1308
思路
要判断是所给的边组成的图形是不是树?,要下面的情况要考虑
1.没有自环:某一条边的起点与终点是相同的一个节点 -->解决:并查集在合并的时候去检查或者判读起点是否等于终点
2.没有环:并查集在合并的时候去检查
3.不能是森林:有多个根节点 --> 看入度为0的点有几个
4.空树是一棵树:没有节点的树🌲
并查集代码
#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#include <stack>
#include <vector>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
const int mod=10007;
using namespace std;
int pre[maxx],v[maxx];
int flag,maxn;
void init()
{
for(int i=0; i<maxx; i++)
{
pre[i]=i;
v[i]=0;
}
maxn=0;
flag=1;
}
int getf(int a)
{
if(a==pre[a])
return a;
int tmp=getf(pre[a]);
return tmp;
}
void mer(int a,int b)
{
int fa=getf(a);
int fb=getf(b);
if(fa!=fb)
pre[fb]=fa;
if(b!=fb || fa==fb)//体现在这里,多加的条件
flag=0;
}
int main()
{
int a,b,k=0;
init();
while(~scanf("%d%d",&a,&b) && (a!=-1 && b!=-1))
{
if(a==0 && b==0)
{
int ans=0;
for(int i=1; i<=maxn; i++)
{
if(v[i] && pre[i]==i)
ans++;
}
if(ans>1)
flag=0;
if(flag)
printf("Case %d is a tree.\n",++k);
else
printf("Case %d is not a tree.\n",++k);
init();
continue;
}
maxn=max(max(a,b),maxn);
v[a]=1;
v[b]=1;
mer(a,b);
}
return 0;
}
有缺陷代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
#define ll long long
#define db double
#define INF 0x3f3f3f3f
const int mxn = 1e6 + 10;
int bar[mxn];
int ar[mxn];
int main()
{
/* freopen("A.txt","r",stdin); */
/* freopen("Ans.txt","w",stdout); */
int s, e, Case = 1;
while(scanf("%d %d", &s, &e) && s >= 0)
{
int zi_huan = 0;
if(s == 0 && e == 0)
{
printf("Case %d is a tree.\n", Case ++);
continue;
}
else
{
if(s == e)
zi_huan = 1;
}
int edge = 1;
memset(bar, 0, sizeof(bar));
memset(ar, 0, sizeof(ar));
int mx = -1;
bar[e] ++;
ar[s] = 1, ar[e] = 1;
mx = max(mx, max(s, e));
while(scanf("%d %d", &s, &e) && s != 0)
{
if(s == e) zi_huan = 1;
edge ++;
bar[e] ++;
ar[s] = 1, ar[e] = 1;
mx = max(mx, max(s, e));
}
int cnt_0 = 0, big_1 = 1, cnt_node = 0;
for(int i = mx; i >= 1; i --)
{
if(bar[i] > 1)
{
big_1 = 0;
break;
}
if(bar[i] == 0 && ar[i])
{
cnt_0 ++;
if(cnt_0 > 1)
break;
}
if(ar[i])
cnt_node ++;
}
if(cnt_0 == 1 && big_1 && ! zi_huan)
printf("Case %d is a tree.\n", Case ++);
else
printf("Case %d is not a tree.\n", Case ++);
}
return 0;
}