题目链接在这里
题目大意:
给出点和边,问能否构成一棵树
思路:
用并查集水过去就行了。hdu1272和这道题一样的,就是换了个题面和输出。hdu1272
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(i, n) for(int i = 0; i < n; ++i)
#define clr(x) memset(x, 0, sizeof(x))
using namespace std;
const int MaxN = 1e5 + 10;
int par[MaxN], r[MaxN];
bool vis[MaxN];
int n, cnt, num_edge;
bool flag;
void init(){
rep(i, MaxN) par[i] = i;
clr(r);
clr(vis);
n = cnt = num_edge = 0;
flag = true;
}
int Find(int x){
if(x == par[x]) return x;
return par[x] = Find(par[x]);
}
bool unite(int x, int y){
x = Find(x);
y = Find(y);
if(x == y) return false;
if(r[x] < r[y]) par[x] = y;
else{
par[y] = x;
if(r[x] == r[y]) ++r[x];
}
return true;
}
int main(){
ios::sync_with_stdio(false);
int x, y;
init();
int Case = 0;
while(scanf("%d %d", &x, &y)){
if(x == -1 && y == -1) break;
if(x == 0 && y == 0){
if(cnt == 0){
cout << "Case " << ++Case << " is a tree." << endl;
}
else{
if(flag && num_edge == cnt - 1) cout << "Case " << ++Case << " is a tree." << endl;
else cout << "Case " << ++Case << " is not a tree." << endl;
}
init();
continue;
}
++num_edge;
if(!vis[x]){
++cnt;
vis[x] = true;
}
if(!vis[y]){
++cnt;
vis[y] = true;
}
if(!unite(x, y))
flag = false;
}
return 0;
}