hdu3172 Virtual Friends
很有意思的一道题:
两个人成为朋友,他们就有关系,题目给出m句话,每一句是两个人,表示两个成为朋友,然后叫你求这与这两个人有关系的集合中有多少个人。
以为stl过不了,结果过了,直接用map映射就好了,如果不在同一集合,就暴力合并(时间卡在这里)。
注意一下这个题目的输入。

#include<stdio.h> #include<string.h> #include<string> #include<iostream> #include<map> #include<set> using namespace std; const int N = 100005; map<string,int>bs; set<string>as[N]; int main() { int i,j,k,t,n,m; set<string>::iterator pos; map<string,int>::iterator posa,posb; while(scanf("%d",&t)!=EOF) while(t--) { for(i = 0; i < N; ++ i) as[i].clear(); bs.clear(); char a[25],b[25]; scanf("%d",&n); if(!n)continue; scanf("%s %s",a,b); k = 0; bs[a] = k; bs[b] = k; as[k].insert(a); as[k].insert(b); puts("2"); while(--n) { scanf("%s %s",a,b); posa = bs.find(a); posb = bs.find(b); if((posa==bs.end())&&(posb==bs.end())) { puts("2"); bs[a] = ++k; bs[b] = k; as[k].insert(a); as[k].insert(b); }else if(posa==bs.end()){ int idb = bs[b]; as[idb].insert(a); bs[a] = idb; printf("%d\n",as[idb].size()); }else if(posb==bs.end()){ int ida = bs[a]; as[ida].insert(b); bs[b] = ida; printf("%d\n",as[ida].size()); }else{ int ida = bs[a]; int idb = bs[b]; if(ida==idb)printf("%d\n",as[ida].size()); else if(as[ida].size()<as[idb].size()) { for(pos = as[ida].begin(); pos != as[ida].end(); ++pos) { bs[*pos] = idb; as[idb].insert(*pos); } as[ida].clear(); printf("%d\n",as[idb].size()); }else{ for(pos = as[idb].begin(); pos != as[idb].end(); ++pos) { bs[*pos] = ida; as[ida].insert(*pos); } as[idb].clear(); printf("%d\n",as[ida].size()); } } } }return 0; }
另外也可以用并差集做,时间控制得很好。
http://hi.baidu.com/492943457/blog/item/7cfae63a14892de015cecbce.html