1. 程式人生 > >計蒜客 網路交友(map +set +並查集)

計蒜客 網路交友(map +set +並查集)

這道題我為什麼寫題解, 就是因為我莫名其妙的就秒了。可能就是一個大水題吧
還有就是這道題用map+ set寫的真滴快!
題目:在網路社交的過程中,通過朋友,也能認識新的朋友。在某個朋友關係圖中,假定 A 和 B 是朋友,B 和 C 是朋友,那麼 A 和 C 也會成為朋友。即,我們規定朋友的朋友也是朋友。

現在要求你每當有一對新的朋友認識的時候,你需要計算兩人的朋友圈合併以後的大小。
輸入格式

第一行:一個整數 n(n\leq 5000)n(n≤5000),表示有 nn 對朋友認識。

接下來 nn 行:每行輸入兩個名字。表示新認識的兩人的名字,用空格隔開。(名字是一個首字母大寫後面全是小寫字母且長度不超過 20 的串)。

輸出格式

對於每一對新認識的朋友,輸出合併以後的朋友圈的大小。

樣例輸入

3
Fred Barney
Barney Betty
Betty Wilma
樣例輸出

2
3
4

AC程式碼講解:

#include<iostream>
#include<map>
#include<set>
using namespace std;
int pa[10010];

void inline init(){//有五千組朋友關係,最多有10000個人
    for(int i = 1; i <= 10000;i++)
     pa[i] = i;
}

int
find(int x){ if(x != pa[x]) pa[x] = find(pa[x]); return pa[x]; } void unite(int x,int y){ int fx = find(x); int fy = find(y); if(fx != fy) pa[fx] = fy; } int main(){ int T; cin >> T; string a , b; set<string>se;//建立一個集合 map<string,int>mp;//建立一個對映
int p = 1; init(); while(T--){ cin >> a >> b; if(!se.count(a)){//判斷a這個人有沒有出現過 se.insert(a);//沒出現就加入集合 mp[a] = p++;//沒出現就給一個新的編號 } if(!se.count(b)){//同上判斷b se.insert(b); mp[b] = p++; } unite(mp[a],mp[b]);//聯合 int ans = 0; for(int i = 1; i < p; i++) //判斷和以這個為根節點的人有多少個 if(find(i) == find(mp[b])) ans++; cout << ans << endl; } return 0; }