hdu1325 Is It A Tree?並查集
阿新 • • 發佈:2019-01-29
題目地址
單看題目的話和hdu1272是一樣的。但是hdu1272的博文中我也說了,資料比較水,所以我用非並查集的方法就AC了。但是這題的資料沒那麼水,要用到並查集來解。這題的盲點和重點有這麼幾個:
- 輸入不是以-1 -1結束,而是以兩個負數結束
- 需要用並查集來判斷是不是隻有一個“根”
- 需要判斷所有節點的入度是否大於1
- 本題輸入的格式,也要注意一下。
比如這個圖中,8的父節點有兩個那麼parent[8]應該如何儲存呢??所以我們可以把它看成無向圖,無所謂父子,只需把關係集合merge合併就好了。這種有多個父節點的情況,就使用一個記錄入度的陣列來標記就好了。
#include<iostream> using namespace std; const int MAX=1000; int rudu[MAX+10];//入度 int parent[MAX+10]; int root[MAX+10];//儲存是否為根 bool flag = true; int r=0; int getParent(int a) { int k=parent[a]; if(parent[a]!=a) { parent[a]=getParent(parent[a]); } return parent[a]; } void merge(int a,int b) { int p1=getParent(a); int p2=getParent(b); if(p1==p2) return; parent[p1]=p2; root[p2]=1; root[p1]=0; } void init() { r=0; flag = true; for(int i=0;i<=MAX;i++) { parent[i]=i; rudu[i]=0; root[i]=0; } } void main() { int a,b,c=1; init(); while(cin>>a>>b,a>=0&&b>=0) { if(!a&&!b) { for(int i=0;i<=MAX;i++) { if(rudu[i]>1) flag = false; if(root[i]) r++; } if(r>1) flag=false; if(flag) cout<<"Case "<<c++<<" is a tree."<<endl; else cout<<"Case "<<c++<<" is not a tree."<<endl; init(); continue; } if(getParent(a)!=getParent(b)) merge(a,b); rudu[b]++; } }