有點意思的並查集
阿新 • • 發佈:2018-07-23
set 歸並 但是 scanf http 他在 ring href 怎麽
K - How Many Answers Are Wrong HDU - 3038
題目大意:兩個人玩遊戲,一個人說一個區間內的數的和,然後判斷她說的有多少句和之前說過的沖突的。
一開始想的用一個數就代表他到根節點裏的數和,但是在路徑壓縮時明顯不對,因為已知[1,8],[8,10]並不能推出[1,10],但如果是(1,8],(8,10]就可以推出(1,10]。所以關鍵在於一個左開右閉的區間。
1 #include<stdio.h> 2 struct Extent{ 3 int gen,sum;//sum為區間(gen,x]內的和 4 }E[201108]; 5 int gui(intx); 6 int bing(int x,int y,int z); 7 int main() 8 { 9 int n,m,i; 10 while(scanf("%d%d",&n,&m)!=EOF) 11 { 12 for(i=0;i<=n;i++) 13 { 14 E[i].gen=i; 15 E[i].sum=0;//一開始為空集即0 16 } 17 int x,y,z,ans=0; 18 while(m--) 19 {20 scanf("%d%d%d",&x,&y,&z); 21 ans+=bing(x-1,y,z);//每次給的是[x,y]的值,所以歸並時是將x-1和y歸並 22 } 23 printf("%d\n",ans); 24 } 25 return 0; 26 } 27 int gui(int x) 28 { 29 if(E[x].gen==x) 30 return x; 31 int y=E[x].gen,z=gui(E[x].gen);//先回溯更新父節點和根節點的權32 E[x].sum=E[y].sum+E[x].sum;//(a,b]和為sum1 (b,c]和為sum2 則(a,c]為sum1+sum2 33 return E[x].gen=z; 34 } 35 int bing(int x,int y,int z) 36 { 37 int bx=gui(x); 38 int by=gui(y); 39 if(bx==by) 40 { 41 if(E[y].sum-E[x].sum!=z) 42 return 1; 43 } 44 else 45 { 46 E[by].gen=bx; 47 E[by].sum=E[x].sum-E[y].sum+z;//向量加法 48 } 49 return 0; 50 }
E - Peculiar apple-tree CodeForces - 931D
題目大意;有一顆蘋果樹,有很多花(??我英語不好),然後第一朵在樹跟,其他在樹枝,每次每朵花會一個結果,然後同時往下掉p的花中,掉到同一朵花的時,偶數個的蘋果會全部碰碎,奇數個的只剩一個。問一個人在第一朵花能撿到的蘋果數量。
畫圖來理解就是看他們最後能不能掉到第一朵花,而怎麽處理同時掉落呢,距離。用它們到第一距離就可以代表時間了。註意距離不是高度,比如高度3的話蘋果掉到1,高度7的話的蘋果掉到3,那高度3 的話與第一朵花的距離是1,高度7與第一朵花的距離是2。這樣,然後就是一個並查集。然後看它們到第一朵花的距離,相同的就會碰到一起。
1 #include<stdio.h> 2 #include<string.h> 3 struct Apple{ 4 int gen,dis;//gen是這個蘋果最後會掉到哪朵花 dis是這朵花到gen的距離 5 }A[101108]; 6 int book[101108]; 7 inline int gui(int x){ 8 if(A[x].gen==x) 9 return x; 10 return A[x].gen=gui(A[x].gen); 11 } 12 int main() 13 { 14 int n,i,p; 15 scanf("%d",&n); 16 for(i=1;i<=n;i++) 17 { 18 A[i].gen=i;//一開始蘋果結在這個花這裏 19 A[i].dis=0;//距離沒得說就是0 20 } 21 for(i=2;i<=n;i++) 22 { 23 scanf("%d",&p); 24 A[gui(i)].gen=gui(p);//並查集,讓它的gen為最後掉到的地方 25 A[i].dis=A[p].dis+1;//而它到gen的距離就是它下一個掉落的地方的距離+1 26 } 27 memset(book,0,sizeof(book)); 28 for(i=1;i<=n;i++)//從第一個蘋果開始 29 if(gui(i)==1)//如果能掉到第一朵花 30 book[A[i].dis]++; 31 //因為蘋果都是同時掉落,所有用距離來代表時間,如果到達gen的距離相同說明他們會碰到一起 32 //book就統計最終能到第一朵花的花的距離,看一下每個距離相同的有多少個 33 int ans=0; 34 for(i=0;i<n;i++) 35 ans+=book[i]%2;//最後對2取模,同時間如果有偶數個蘋果碰到一起就全部銷毀,奇數個只剩一個 36 printf("%d\n",ans); 37 return 0; 38 }
有點意思的並查集