1. 程式人生 > >【NOI2002】銀河英雄傳說

【NOI2002】銀河英雄傳說

clas clu 是把 logs 操作 std 根節點 noi 就是

 1 #include<cstdio>
 2 #include<cstdlib>
 3 int T,x,y,p[30001],a[30001],r[30001]; //r[i]表示i號戰艦和它的隊頭戰艦之間的距離 
 4 char ch[2];                           //a[i]是代表為i的隊一共有多少戰艦
 5 void init(){                          //實際上,如果用r[x]表示數目的話對於只有一個結點和兩個結點的情況 
 6     for(int i=1;i<=30000;i++)         //就不好區分,設為距離可以便於統一處理
7 p[i]=i,a[i]=1; //為什麽需要a[],因為每次UNION操作是把隊列置於另一個隊列的隊尾 8 } //為了得到兩個隊頭的距離,就需要有這樣的記錄 9 int find(int x){ //始終註意到,UNION本質是對“代表元素”的操作 10 if(x!=p[x]){ 11 int px=find(p[x]);//找到當前結點x的根節點,同時在x以上的結點都完成了r[x]的更新,包括r[p[x]]
12 r[x]+=r[p[x]]; //加上距離得到當前結點x對根節點px的距離 13 p[x]=px; 14 } 15 return p[x]; 16 } 17 void Union(int x,int y,int px,int py){ 18 p[px]=py; //直接設px指向py 19 r[px]=a[py]; //那麽此時px和py之間的距離就是py隊列的元素數目 20 a[py]+=a[px]; //因為實際上是把px置於py隊尾,那麽py隊列現在的數目就是兩者之和
21 } 22 int main() 23 { 24 init(); 25 scanf("%d",&T); 26 while(T--){ 27 scanf("%s%d%d",ch,&x,&y); 28 int px=find(x),py=find(y); 29 if(ch[0]==M) Union(x,y,px,py); 30 else{ 31 if(px!=py) printf("-1\n"); 32 else printf("%d\n",abs(r[x]-r[y])-1); //數目=距離-1 33 } 34 } 35 }

【NOI2002】銀河英雄傳說