火影忍者之~忍者村

火影忍者之~忍者村
Time Limit: 2000 MS Memory Limit: 65536 K
Total Submit: 287(114 users) Total Accepted: 152(99 users) Rating:  Special Judge: No
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
",ans);*/
        set<int> s;
        for(int i=1;i<=l;i++)
        s.insert(findteam(team[i]));
        printf("%d
",s.size());

    }
    return 0;
}
原文地址:https://www.cnblogs.com/stepping/p/6506870.html