火影忍者之~忍者村 | ||||||
| ||||||
Description | ||||||
忍者村是忍者聚居的村子,相等于国家的军事力量。绝大部分村民都是忍者,有一些忍者会在村内开设书店、餐厅等,不过大部分忍者都是为村子执行任务的忍者,以赚取酬劳,并于战时为国家出战。村子亦会培训年轻村民成为忍者。 忍者们一般以三人一组执行各种任务,现在假设不同村子的忍者不会一起执行任务,给出一些忍者的组合,判断由这些组合能确定的最多的忍者村的个数。 | ||||||
Input | ||||||
第一行是整数n,表示已知n组忍者组合,接下来n行每行三个忍者的名字,n不超过1000,每个名字不长于10. | ||||||
Output | ||||||
对于每组输入,输出在这些忍者最多属于多少个忍者村。 | ||||||
Sample Input | ||||||
7 a b c c d e d e f g k h l m n o p q h r p | ||||||
Sample Output | ||||||
3 | ||||||
Source | ||||||
2012 Spring Contest 3 - STL |
题解:并查集+hash的map表达
#include <iostream> #include<cstdio> #include<cstring> #include<string> #include<set> #include<algorithm> #include<map> using namespace std; int n,l; map<string,int> mp; int team[3005]; char ch1[15],ch2[15],ch3[15]; int num(char *s) {map<string,int>::iterator it;it=mp.find(s);if (it!=mp.end()) return it->second;else {mp[s]=++l; team[l]=l; return l;} } int findteam(int k) {if (team[k]!=k){team[k]=findteam(team[k]);return team[k];}else return team[k]; } int main() {while(~scanf("%d",&n)){mp.clear(); l=0;for(int i=1;i<=n;i++){scanf("%s%s%s",&ch1,&ch2,&ch3);int n1=num(ch1);int n2=num(ch2);int n3=num(ch3);n1=findteam(n1);n2=findteam(n2);n3=findteam(n3);team[n2]=n1;team[n3]=n1;/*if (n1!=n2) team[n2]=n1;if (n1!=n3) team[n3]=n1;if (n2!=n3) team[n3]=n2;这样写就RE了,训练赛时,re到崩溃。这种写法很矛盾吧*/}/*for(int i=1;i<=l;i++) team[i]=findteam(i);sort(team+1,team+1+l);int ans=0;for(int i=1;i<=l;i++)if(team[i]!=team[i-1]) ans++;printf("%d\n",ans);*/set<int> s;for(int i=1;i<=l;i++)s.insert(findteam(team[i]));printf("%d\n",s.size());}return 0; }