HDU 1272 (並查集)
阿新 • • 發佈:2018-12-11
題意:上次Gardon的迷宮城堡小希玩了很久(見Problem B),現在她也想設計一個迷宮讓Gardon來走。但是她設計迷宮的思路不一樣,首先她認為所有的通道都應該是雙向連通的,就是說如果有一個通道連通了房間A和B,那麼既可以通過它從房間A走到房間B,也可以通過它從房間B走到房間A,為了提高難度,小希希望任意兩個房間有且僅有一條路徑可以相通(除非走了回頭路)。小希現在把她的設計圖給你,讓你幫忙判斷她的設計圖是否符合她的設計思路。比如下面的例子,前兩個是符合條件的,但是最後一個卻有兩種方法從5到達8。
思路:
並查集判環,頂點數=邊數-1即可, 注意無頂點和邊時是滿足條件的,輸出Yes。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int maxn=100005; const double eps=1e-8; const double PI = acos(-1.0); ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } int pre[maxn]; void init() { for(int i=1;i<=maxn;i++) { pre[i]=i; } } int find(int x) { if(x==pre[x]) return x; else { int root=find(pre[x]); return pre[x]=root; } } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); int a,b; while(cin>>a>>b) { set<int> s; if(!a&&!b) { cout<<"Yes"<<endl; continue; } init(); int flag=0,cnt=1; s.insert(a),s.insert(b); if(a==-1&&b==-1) break; int fa=find(a),fb=find(b); if(fa!=fb) pre[fa]=fb; else flag=1; for(;;) { int u,v; cin>>u>>v; if(!u&&!v) break; cnt++; s.insert(u),s.insert(v); int fu=find(u),fv=find(v); if(fu!=fv) pre[fu]=fv; else flag=1; } if(s.size()!=cnt+1) flag=1; if(flag) cout<<"No"<<endl; else cout<<"Yes"<<endl; } return 0; }