思路
要想构成一棵树,那么就要满足,每一次的连边都是在两个不同的集合间进行的,这个用并查集就可以做。
还要将所有的节点都要连起来,所以记录一下节点数和边数,利用set就可以得到不同的节点个数,然比较是否满足节点数等于边数加一。
再对空树进行特判。
代码
#include <algorithm>
#include <set>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1000;
int par[maxn+10];
int get_par(int a)
{
if(par[a]<0) return a;
else return par[a] = get_par(par[a]);
}
void merge(int a, int b)
{
int pa = get_par(a);
int pb = get_par(b);
if(pa!=pb) par[pa] = pb;
}
bool query(int a, int b)
{
return get_par(a) == get_par(b);
}
int main()
{
int a, b, t=1;
unsigned edge;
set<int> node;
bool flag;
while(scanf("%d%d", &a, &b) && a!=-1)
{
if(a==0&&b==0)
{
printf("Case %d is a tree.\n", t++);
continue;
}
memset(par, -1, sizeof(par));
merge(a, b);
flag = true;
edge = 1;
node.clear();
node.insert(a);
node.insert(b);
while(scanf("%d%d", &a, &b) && a)
{
if(!flag) continue;
if(query(a, b))
{
flag = false;
}
else
{
merge(a, b);
node.insert(a);
node.insert(b);
edge++;
}
}
if(node.size()!=edge+1) flag = false;
if(flag) printf("Case %d is a tree.\n", t++);
else printf("Case %d is not a tree.\n", t++);
}
return 0;
}