判断一个图是否为树(有向图以及无向图)

时间:2025-04-07 18:47:21
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<bitset> #include<queue> using namespace std; typedef long long ll; typedef pair<int,int> PII; const int N = 200007, M = 5000007, INF = 0x3f3f3f3f; int fa[N], n, m; bool vis[N]; int Find(int x) { if(fa[x] == x)return x; return fa[x] = Find(fa[x]); } bool unions(int x, int y) { int fx = Find(x); int fy = Find(y); if(fx != fy){ fa[fy] = fx;//注意合并的是原来的点 return true; } return false;//有环,不是树 } int x, y; int kcase; int main() { while(scanf("%d%d", &x, &y)){ kcase ++ ; bool flag = true; if(x < 0 || y < 0) break; if(x == 0 && y == 0){ printf("Case %d is a tree.\n", ++ kcase); continue; } for(int i = 1; i < N; ++ i){ fa[i] = i; vis[i] = 0; } while(!(x == y && y == 0)){ vis[x] = true; vis[y] = true; //!因为树只有一条边指向节点,根没有边指向根节点,所以如果有两个及以上的边指向它就说明不是树 if(Find(y) != y) flag = false; else if(unions(x, y) == 0){//有环,不是树 flag = false; } scanf("%d%d", &x, &y); } int tot = 0; for(int i = 1; i < N; ++ i){ if(vis[i] && fa[i] == i)//找有几个根 tot ++ ; /*if(tot > 1){ flag = 1; break; }*/ } if(tot != 0 && tot != 1)flag = false; //cout << tot << "ok" <<endl; //入度大于1了或者成树林了 if(flag) printf("Case %d is a tree.\n", kcase); else printf("Case %d is not a tree.\n", kcase); } return 0; }