這題按照江老師告訴我們探索題目的方法,我就列舉了一些不能上車的一些例子:
1 2 1 3 2 4 4 3 -1 |
4 6 3 4 2 3 1 4 2 5 6 5 -1 |
結果是這樣子:
於是就發現,似乎能組成爆炸化合物的,必定是有環形的。
又通過幾組數據驗證得到,這個發現是正確的。
接下來就簡單了,因爲之前做過tree,現在做判斷環形的題目就比較容易。
參考程序:
#include <iostream> #include <fstream> using namespace std; int fa[1000001],line[1000001],point[1000001]; //還不知道數據範圍,所以先搞這麼多 int u_f(int x) //並查集找根並壓縮路徑 { int root=x; while(fa[root]!=root) root=fa[root]; while(fa[x]!=x) { int y=fa[x]; fa[x]=root; x=y; } return root;
} int main() { freopen("explosion.in","r",stdin); freopen("explosion.out","w",stdout); int ans=0;
//把 i 的父節點指向自己,並初始化邊數與點數 for(int i=0;i<=100000;i++) { fa[i]=i; line[i]=0; point[i]=1; } while(1) { int x,y; scanf("%d",&x); //這裏就是怕數據較大時cin會超時 if(x==-1) break; //如果結束(-1)則退出循環 scanf("%d",&y); int fx=u_f(x); int fy=u_f(y); if(fx==fy) //如果爲環形,邊數加 1 line[fx]++; else //若不是,則連接兩個節點,並且把邊數與點數也隨之改變 { fa[fy]=fx; line[fx]+=line[fy]+1; point[fx]+=point[fy]; } if(point[fx]-line[fx]!=1) //如果這個連通塊不是一棵樹(即爲環形),累加器累加 { ans++; line[fx]--; //因爲並沒有把它放上飛機,所以邊數也要變回來 } } printf("%d",ans);
return 0; }
|