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; }
相关文章推荐
- POJ 1272 小希的迷宫【并查集+无向图判断是否有环 PS:和前一篇判断入度是否为1的很像】
- POJ 1272 小希的迷宫【并查集+无向图判断是否有环 PS:和前一篇判断入度是否为1的很像】
- HDOJ1272(并查集,判断是否为树)
- HDOJ1272并查集加判断森林
- hdu 1272 判断所给的图是不是生成树 (并查集)
- HDU:1272 小希的迷宫(并查集+无向图成树判断)
- hdoj--1272--小希的迷宫(并查集)
- hdoj 3435 A new Graph Game 【无向图判断权值最小哈密顿环】【KM算法】
- HDU 1272 小希的迷宫 并查集 (判断任意2个点是否有且仅有一条路径可以相通)
- HDOJ 1272 小希的迷宫(并查集)
- hdoj 1272 小希的迷宫(并查集)
- HDU 1272 小希的迷宫(并查集:判断连通且结构为树)
- HDOJ 1272 小希迷宫 (并查集)
- HDU 1272 小希的迷宫 并查集 (判断任意2个点是否有且仅有一条路径可以相通)
- hdoj2120 Ice_cream's word I(并查集,判断环的个数)
- HDU - 1272 小希的迷宫 并查集集合数判断
- HDU 1272 小希的迷宫 并查集 (判断任意2个点是否有且仅有一条路径可以相通)
- HDOJ 1272 小希的迷宫(基础并查集)
- HDU-1272 小希的迷宫 (并查集、判断图是否为树)
- HDOJ1272~小希的迷宫~并查集