【解題報告】 ZOJ 3641 Information Sharing
阿新 • • 發佈:2019-02-09
/* ZOJ 3641 Information Sharing 並查集+模擬 題意:給出了一些人對應了幾個數字(information) 然後又有一些人會分享數字(share information)分享是雙向的,取並集 最後會問某些人在此刻擁有哪些數字(information he has gotten) 做法:由於數字的個數才1000(at most 1000 distinct information) 所以每個人用一個集合表示,每個人集合的大小不會很大,然後分享的操作就是 並查集並的過程,而輸出只需要直接輸出集合的大小即可。 */ #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <vector> #include <map> #include <set> #define CLR(c,v) memset(c,v,sizeof(c)) using namespace std; const int N = 1e5 + 5; map <string ,int>list; set<int > dset[N]; int father[N]; int n_people = 0; int getid(string name){ if(list.find(name) == list.end()){ // 在這裡初始化 list[name] = ++n_people; father[n_people] = n_people; dset[n_people].clear(); } return list[name]; } int find(int x){ if(x == father[x]) return x; return father[x] = find(father[x]); } void Union(int name1,int name2){ int f1 = find(name1); int f2 = find(name2); if(f1 == f2)return; if(dset[f1].size() > dset[f2].size()){ swap(f1,f2); } for(set <int >::iterator it = dset[f1].begin() ; it != dset[f1].end() ; it++){ dset[f2].insert(*it); } father[f1] = f2; } int main(){ //freopen("in.txt","r",stdin); int T; while(~scanf("%d",&T)){ list.clear(); n_people = 0; while(T--){ string ins,name1; cin >> ins >> name1; int id1 = getid(name1); if(ins[0] == 'a'){ int m;scanf("%d",&m); for(int i = 0; i < m ; i++){ int a;scanf("%d",&a); dset[id1].insert(a); } }else if(ins[0] == 's'){ string name2; cin >> name2; Union( id1 , getid(name2)); }else{ id1 = find(id1); cout << dset[id1].size() << endl; } } } return 0; } /* 這個是用了兩個map的程式,TLE了。。。 後來看了看人家寫的,發現轉成int的就可以了。。 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <vector> #include <map> #include <set> #define CLR(c,v) memset(c,v,sizeof(c)) using namespace std; const int N = 1000 + 5; map <string ,string>father; map <string ,set<int > > sdmap; void debug(){ } string find(string& name){ if(name == father[name]) return name; return father[name] = find(father[name]); } void Union(string& name1,string& name2){ string f1 = find(name1); string f2 = find(name2); if(sdmap[f1].size() > sdmap[f2].size()){ swap(f1,f2); } for(set <int >::iterator it = sdmap[f1].begin() ; it != sdmap[f1].end() ; it++){ sdmap[f2].insert(*it); } father[f1] = f2; } int main(){ //freopen("in.txt","r",stdin); int T; while(~scanf("%d",&T)){ sdmap.clear(); father.clear(); while(T--){ string ins; cin >> ins; if(ins[0] == 'a'){ string name;int m; cin >> name >> m; father[name] = name; for(int i = 0; i < m ; i++){ int a;scanf("%d",&a); sdmap[name].insert(a); } }else if(ins[0] == 's'){ string name1,name2; cin >> name1 >> name2; Union(name1,name2); }else{ string name; cin >> name; name = find(name); cout <<sdmap[name].size() << endl; } } } return 0; } */