您的位置:首页 > 其它

HDOJ-1272(判断无向图是不是树,BFS || 并查集)

2014-07-20 15:51 288 查看
题目意思就是给出图上一些边,判断这个图是不是树,一开始没有注意到输入一上来就0 0的情况,WA了一次,看了discuss加上特判之后就A了,用了个水水的BFS:



#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define MAX_ID    100000

vector<int> neighbour[MAX_ID + 1];
int  countOfId;
bool vis[MAX_ID + 1];
int  pre[MAX_ID + 1];

bool bfs(int st)
{
//initilaize flag
memset(vis, false, sizeof(vis));
//process
int visited = 0;
queue<int> q;
q.push(st);
pre[st] = -1;
vis[st] = true;

while(!q.empty()){
int x = q.front(); q.pop();
++visited;
const vector<int>& v = neighbour[x];
for(int i = 0, n = v.size(); i < n; ++i){
int y = v[i];
if(y == pre[x]) continue;
else if(vis[y]) return false;//back edge or one node with several parents
else{
q.push(y);
pre[y] = x;
vis[y] = true;
}
}
}
return visited == countOfId;//there may exist several CC
}

int main()
{
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);

int x, y, i, start;
while(true){
//initialize
countOfId = 0;
for(i = 1; i <= MAX_ID; ++i){
neighbour[i].clear();
vis[i] = false;
}
//input
scanf("%d %d", &x, &y);
if(x == -1) break;
if(x == 0){
puts("Yes");
continue;
}
start = x;
do{
if(!vis[x]){
vis[x] = true;
++countOfId;
}
if(!vis[y]){
vis[y] = true;
++countOfId;
}
neighbour[x].push_back(y);
neighbour[y].push_back(x);
}while(scanf("%d %d", &x, &y), x);
//bfs
if(bfs(start)) puts("Yes");
else puts("No");
}
return 0;
}

实际上判断树用并查集做更高效(如果结构是树,则并查集可以将所有节点通过边归并到单根):



#include <stdio.h>
#include <string.h>
#define MAX_ID    100000

int  father[100001];
char used[100001];

int Find(int x){
while(father[x] != -1) x = father[x];
return x;
}
void Union(int x, int y)
{
if(x < y) father[y] = x;
else father[x] = y;
}
int existSingleRoot()
{
int i = 1, cnt = 0;
for(; i <= MAX_ID; ++i){
if(used[i] && father[i] == -1){
if(++cnt > 1) return 0;
}
}
return cnt == 1;
}

int main()
{
int x, y, px, py, i, initialized = 0, flag;
while(1){
/* initialize */
if(!initialized){
memset(father, 0xff, sizeof(father));
memset(used, 0, sizeof(used));
initialized = 1;
}
/* input */
scanf("%d %d", &x, &y);
if(x == -1) break;
if(x == 0){
puts("Yes");
continue;
}
flag = 1;
do{
used[x] = used[y] = 1;
px = Find(x);
py = Find(y);
if(px == py && px != -1){
flag = 0;
break;
}
else Union(px, py);
}while(scanf("%d %d", &x, &y), x);
/* input rest */
while(x) scanf("%d %d", &x, &y);
/* check if only one root */
if(flag && existSingleRoot()) puts("Yes");
else puts("No");
initialized = 0;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: