思路:其实这道题目就是判断是否为一颗树,所以抓住树的充分必要条件就可以了。
比如树有n个顶点n-1条边,一个连通分量而不是森林,至于实现形式则不是固定的,我用的BFS
BFS判断连通,且满足n个顶点n-1条边.
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <queue>
using namespace std;
const int maxn = 100010;
vector<int> v[maxn+10];
queue<int> Q;
//Accepted 1002 140 MS 3184 KB GNU C++ Achiberx
void BFS(int edge_number) {
bool ok = true;
bool vis[maxn];
int cnt = 0; // the number of node.
int start;
for(int i = 1; i <= 100000; i++) {
if(v[i].size()) {
start = v[i][0];
break;
}
}
while(!Q.empty()) Q.pop();
memset(vis, false, sizeof(vis));
vis[start] = true; // have been visited.
cnt++;
Q.push(start);
int tmp;
while(!Q.empty()) {
tmp = Q.front();
Q.pop();
for(int i = 0; i < (int)v[tmp].size(); i++) {
int point = v[tmp][i];
if(!vis[point]) {
cnt++;
vis[point] = true;
Q.push(point);
}
}
}
// connected.
for(int i = 1; (i <= 100000 && ok); i++) {
if(v[i].size()) {
if(vis[i]) continue;
else {
ok = false;
break;
}
}
}
if(edge_number+1 == cnt);
else ok = false;
if(ok) printf("Yes\n");
else printf("No\n");
}
int main(void) {
bool loop = true;
while(loop) {
int x, y;
int edge_num = 0;
for(int i = 0; i <= 100000; i++) v[i].clear();
while(scanf("%d%d", &x, &y) == 2 && (x || y)) {
if(x < 0 && y < 0) {
loop = false;
break;
}
edge_num++;
v[x].push_back(y);
v[y].push_back(x);
}
if(!loop) break;
BFS(edge_num);
}
return 0;
}