小米2013年校園招聘筆試題-簡單並查集
阿新 • • 發佈:2018-12-31
- 題目描述:
-
假如已知有n個人和m對好友關係(存於數字r)。如果兩個人是直接或間接的好友(好友的好友的好友...),則認為他們屬於同一個朋友圈,請寫程式求出這n個人裡一共有多少個朋友圈。
假如:n = 5 , m = 3 , r = {{1 , 2} , {2 , 3} , {4 , 5}},表示有5個人,1和2是好友,2和3是好友,4和5是好友,則1、2、3屬於一個朋友圈,4、5屬於另一個朋友圈,結果為2個朋友圈。
- 輸入:
-
輸入包含多個測試用例,每個測試用例的第一行包含兩個正整數 n、m,1=<n,m<=100000。接下來有m行,每行分別輸入兩個人的編號f,t(1=<f,t<=n),表示f和t是好友。 當n為0時,輸入結束,該用例不被處理。
- 輸出:
-
對應每個測試用例,輸出在這n個人裡一共有多少個朋友圈。
- 樣例輸入:
-
5 3 1 2 2 3 4 5 3 3 1 2 1 3 2 3 0
- 樣例輸出:
-
2 1
#include <stdio.h> int n, m, f[100001],i; int findSet(int x) { int t = x; while (f[x] > 0) x = f[x]; while (t != x) { //路徑壓縮 int q = f[t]; f[t] = x; t = q; } return x; } void unionSet(int x, int y) { int fx = findSet(x); int fy = findSet(y); if (fx != fy) { n--; int tmp = f[fx] + f[fy];//兩個集合個數之和 if (f[fx] < f[fy]) { //大集合 吞併小集合. f[fy] = fx; f[fx] = tmp; } else { f[fx] = fy; f[fy] = tmp; } } } int main() { //freopen("in.txt", "r", stdin); int a,b; while(scanf("%d",&n), n) { scanf("%d", &m); for( i=1; i<=n; i++) f[i] = -1; for(i=0; i<m; i++) { scanf("%d %d", &a,&b); unionSet(a,b); } printf("%d\n", n); } return 0; }