hrbust 哈理工oj 2026 势力较量【并查集】
生活随笔
收集整理的這篇文章主要介紹了
hrbust 哈理工oj 2026 势力较量【并查集】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
| 勢力較量 | ||||||
| ||||||
| Description | ||||||
| 在戰火紛亂的古代有許多小國家。在這些小國家中,就會有一些強大的,一些弱小的。勢力大的就會吞并勢力小的, 形成更大的勢力國家。現在給出你一些目前的國家勢力關系,你能預算出以后的局勢嗎? 為了簡化問題,給每個國家編號,像“國家1”, “國家2”......“國家N” 國家的較量首先從人數上進行比較,人數多的能打贏人數少的。如果兩個國家的人數相同,就根據國家頭目的編號來判斷, 我們假設編號大的國家能打得過編號小的國家。 當兩個國家相遇的時候,就會有一場打斗,且一定要分出勝負,輸的就會歸順于贏得, 形成一個新的國家。 | ||||||
| Input | ||||||
| 多組測試數據,處理到文件結束。對于每組數據: 第一行兩個整數N,M。N為國家個數,M為關系數目。 接下來M行,每行兩個整數u, v。表示國家u,國家v相遇,有一場打斗。 然后試一個整數Q,表示Q個詢問。 接下來Q行,每行一個整數S。 (N<100, M < 100, Q < 100) | ||||||
| Output | ||||||
| Case k: 對于每個詢問,輸出兩個整數, 第一個整數表示S所在國家的頭目,第二個整數表示S所在國家里邊一共有多少個小國家。 | ||||||
| Sample Input | ||||||
| 5 3 1 2 1 3 4 5 2 1 5 5 4 1 2 1 3 1 4 1 5 4 2 3 4 5 | ||||||
| Sample Output | ||||||
| Case 1: 2 3 5 2 Case 2: 2 5 2 5 2 5 2 5 | ||||||
| Source | ||||||
| 2014 Winter Holiday Contes 4 |
問題分三個部分來詳解,初始化部分、merge部分、詢問部分、
首先我們這里關系到連通路點集合問題(某一集合中元素個數)、所以我們需要兩個數組,F【】、J【】、分別表示father和集合元素個數、
merge部分:
按照題意來模擬,首先判斷人數、然后判斷頭目編號、
我們這里把J【find(x)】用來表示x所在國家(集合)一共有多少個元素(小國家)、當merge的時候,如果是F[Y]=X(讓Y的爹是X)同時我們需要J[X]+=J[Y];
int find(int x) {return f[x] == x ? x : (f[x] = find(f[x])); } void merge(int a,int b) {int A,B;A=find(a);B=find(b);if(A!=B){f[B]=A;j[A]+=j[B];//0.0} }知道了J【】數組是如何更新數據的,我們這里對題干要求去做就相對簡單的多了:1、按照人數多少判斷誰贏:給出x,y。我們對應找到J【find(x)】和J【find(y)】、然后判斷誰大誰小就行了、
2、如果人數相等按照頭目編號來判斷誰贏:直接判斷find(x)和find(y)就行了:
while(m--){int x,y;scanf("%d%d",&x,&y);if(j[find(x)]>j[find(y)])//x的人數多于y{merge(x,y);continue;}if(j[find(y)]>j[find(x)])//y的人數多于x{merge(y,x);continue;}if(j[find(x)]==j[find(y)])//人數相等的時候{int X=find(x);int Y=find(y);if(X>Y)//如果x頭目編號大于y{f[Y]=X;j[X]+=j[Y];}if(Y>X)//注意這里不能用else,我用了一發else,實力WA、如果X,Y同集合,就不用動了,我這里疏忽了{f[X]=Y;j[Y]+=j[X];}}}最后的查詢部分相對就容易的多了,最后上完整的AC代碼: #include<stdio.h> #include<string.h> using namespace std; int f[1000]; int j[1000]; int find(int x) {return f[x] == x ? x : (f[x] = find(f[x])); } void merge(int a,int b) {int A,B;A=find(a);B=find(b);if(A!=B){f[B]=A;j[A]+=j[B];} } int main() {int n,m;int kase=0;while(~scanf("%d%d",&n,&m)){for(int i=0;i<=n;i++){f[i]=i;j[i]=1;}while(m--){int x,y;scanf("%d%d",&x,&y);if(j[find(x)]>j[find(y)]){merge(x,y);continue;}if(j[find(y)]>j[find(x)]){merge(y,x);continue;}if(j[find(x)]==j[find(y)]){int X=find(x);int Y=find(y);if(X>Y){f[Y]=X;j[X]+=j[Y];}if(Y>X){f[X]=Y;j[Y]+=j[X];}}}int q;scanf("%d",&q);printf("Case %d:\n",++kase);while(q--){int s;scanf("%d",&s);printf("%d %d\n",find(s),j[find(s)]);}} }
總結
以上是生活随笔為你收集整理的hrbust 哈理工oj 2026 势力较量【并查集】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Shell 自定义函数
- 下一篇: 组装台式计算机配置清单,diy之家 -