思路是用并查集判断连通,然后判断边数+1==点数,就是判断是否为一颗生成树
#include <iostream> #include <set> #include <algorithm> using namespace std; #ifndef ONLINE_JUDGE #include <fstream> ifstream fin("test.txt"); #define cin fin #endif const int MAXN = 100010; int p[MAXN],vis[MAXN],maxv,edge,ok; set<int> s; int find(int x) { return x == p[x] ? x : p[x] = find(p[x]); } void ini() { ok = 1; s.clear(); maxv = edge = 0; memset(vis,0,sizeof(vis)); for(int i = 0; i < 100000; ++i) p[i] = i; } int main() { ios::sync_with_stdio(false); int n,m; ini(); while(cin >> n >> m) { if(n == -1 && -1 == m) break; maxv = max(m,max(maxv,n)); if(!n && !m) { if(edge == 0) //如果只有2个0的情况,直接输出yes { cout << "Yes" << endl; continue; } if(s.size()!=edge+1) { cout << "No" << endl; ini(); continue; } int cnt = 0; for(int i = 1; i <= maxv; ++i) if(vis[i] && p[i] == i) cnt++; if(cnt == 1 && ok) cout << "Yes" << endl; else cout << "No" << endl; ini(); continue; } s.insert(n); s.insert(m); edge++; vis[n] = vis[m] = 1; n = find(n); m = find(m); if(n != m) p[m] = n; else ok = 0; //如果2个点在同一个集合,直接判否,因为构成了回路 } return 0; }