例5.1 暢通工程
#include
using namespace std;
int tree[
1000];
intfindroot
(int x)
}int
main()
int ans=0;
for(
int i=
0;i<=n;i++
)printf
("%d\n"
,ans-1)
;}return0;
}
練1:連通圖
#include
using namespace std;
int tree[
1000];
intfindroot
(int x)
}int
main()
int ans=0;
for(
int i=
0;i<=n;i++)if
(ans>1)
printf
("no\n");
else
printf
("yes\n");
}return0;
}
練3:head of a gang
使用並查集。
建立了兩個結構體,乙個person用於儲存每個人的名字、權重、所在集合的根節點下標。乙個gang用於儲存結果,每個幫派的頭目及幫派的成員。之所以需要第二個結果結構體是因為我在並查集的過程中無法保證根節點為頭目,輸出時沒辦法按名字公升序輸出,所以用乙個結果結構體陣列sort一下再輸入。在建立乙個sum陣列儲存每個集合的總權重,用於與k比較。
牛客網****
#include
#include
#include
#define n 26
using namespace std;
typedef
struct personperson;
typedef
struct ganggang;
//結果結構體儲存頭目和幫派人數
person p[n]
;int sum[n]
;bool cmp
(gang a,gang b)
//字典排序函式
intfindroot
(int x)
}//並查集函式
intmain()
//初始化
while
(n--
)//合併的過程,順便加上集合的總權重
else
sum[p1]
+=weight;
//如果是同乙個集合也要加上權重
}int ans=0;
//儲存幫派數目
gang g[10]
;//結果陣列,26個人幫派最多有8個,10的陣列夠了
for(i=
0;i)strcpy
(g[ans]
.head,p[max]
.name)
;//把頭目名字存進來
ans++
;//接著存下乙個幫派}}
printf
("%d\n"
,ans)
;//輸入幫派數目
sort
(g,g+ans,cmp)
;//按字典sort一下
for(i=
0;i)printf
("%s %d\n"
,g[i]
.head,g[i]
.number)
;//輸出頭目名字和幫派人數
}return0;
//over,哈哈
}
並查集練習
題目描述 假如已知有n個人和m對好友關係 存於數字r 如果兩個人是直接或間接的好友 好友的好友的好友 則認為他們屬於同乙個朋友圈,請寫程式求出這n個人裡一共有多少個朋友圈。假如 n 5 m 3 r 表示有5個人,1和2是好友,2和3是好友,4和5是好友,則1 2 3屬於乙個朋友圈,4 5屬於另乙個朋...
並查集練習
集合的合併與維護和食物鏈那道題一樣。不過多了個裁判。注意到n 500,所以可以列舉裁判,然後判斷是否出現了矛盾。忽略裁判 如果有矛盾,則這個人不是裁判。唯一有點難度的是輸出第幾行判斷出的裁判。原先以為是最後出現裁判的那一行。後來發現應當時列舉其他人時候首次出現矛盾的最大值。仔細想想 這樣這道題就解決...
Friend解題報告 並查集練習
這題並不是很難,僅作為並查集的乙個入門級練習,所要掌握的知識也確實很基礎。實際上,這道題就是問在一定的合併操作後,問最大的集合有多少人。但是同時也要記住,相同的集合不能合併!include using namespace std struct node node point 1000001 int ...