顺丰笔试、学术交流、并查集
之前从没有写过并查集,昨天顺丰笔试,见到其它老哥用并查集很容易就能解决了学术交流的问题。看了大佬ac的java代码,照着写了个c++的并查集。并查集还是挺有用的,在此记录一下,希望加深一下印象。
如有错误,敬请指出。
#include<bits/stdc++.h> using namespace std; int findparent(int a, vector<int> &parent) { int x = a; while(parent[x] != x) x = parent[x]; while(parent[a] != x) { int z = a; a = parent[a]; parent[z] = x; } return x; } void uniontwo(int a, int b, vector<int> &parent) { int ap = findparent(a, parent), bp = findparent(b, parent); if(ap != bp) { parent[ap] = bp; } } int main() { int n,m,k; cin >> n >> m >> k; vector<int> parent(m); map<int, vector<int>> mp; // key is people, value is the man's languages vector<int> people2language(n, -1); vector<bool> show(m, false); for(int i = 0; i < m; i++) { parent[i] = i; } for(int i = 0; i < k; i++) { int people, language; cin >> people >> language; people2language[people-1] = language; if(mp.count(people) == 0) { mp[people] = vector<int>(1, language); }else{ mp[people].push_back(language); } show[language-1] = true; } for(int i = 0; i < n; i++) { if(mp.count(i) > 0) { for(int j = 0; j < mp[i].size()-1; j++){ uniontwo(mp[i][j], mp[i][j+1], parent); } } } int ans = 0; for(int i = 0; i < n; i++) { if(people2language[i] == -1) { ans++; } } set<int> st; for(int i = 0; i < m; i++) { if(show[i]) { st.insert(findparent(i, parent)); } } if(st.size() > 0) { ans = ans + st.size()-1; } cout << ans << endl; return 0; }#笔试题目#