poj 2732 Countdown(East Central North America 2005)
题意:建一个家庭树,找出有第d代子孙的名字,按照要求的第d代子孙的数从大到小输出三个人名,如果有一样大小子孙数的,就按字母序从小到大将同等大小的都输出,如果小于三个人的就全输出。
题目链接:http://poj.org/problem?id=2732
分析:数据量很小,直接建树,枚举暴力输出。我直接套模板用map建树的。
注意:1.每次测试数据时要清空map和vector!!!
2.注意输出要从大到小输出答案,如果答案有一样的按名字的字母序从小到大输出。答案用vector保存,vector排序:sort(v.begin(),v.end(),cmp);
3.注意嵌套模板的使用,map<string,vector<string> >fa;
另,关于建树,可以直接用int类型代替名字的string类型,给每个名字赋予一个编号。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string> 10 #include <cmath> 11 #include <cstdlib> 12 #include <ctime> 13 using namespace std; 14 string name[1005]; 15 map<string,int>mp; 16 map<string,vector<string> >fa; 17 vector<pair<string,int> >ans; 18 vector<string>v; 19 int fin(string na,int gen) 20 { 21 int ans=0; 22 if(gen==0) 23 return 1; 24 for(int i=0;i<mp[na];i++) 25 { 26 if(gen>=0) 27 ans+=fin(fa[na][i],gen-1); 28 } 29 return ans; 30 } 31 int cmp(pair<string,int>p1,pair<string,int>p2) 32 { 33 if(p1.second==p2.second) 34 return p1.first<p2.first; 35 return p1.second>p2.second; 36 } 37 int main() 38 { 39 int t,cnt=1; 40 cin>>t; 41 while(t--) 42 { 43 fa.clear(); //每次样例注意清空数据 44 ans.clear(); 45 mp.clear(); 46 int n,d; 47 cin>>n>>d; 48 int num; 49 for(int i=0;i<n;i++) 50 { 51 cin>>name[i]; 52 cin>>num; 53 string child; 54 mp[name[i]]=num; 55 v.clear(); 56 for(int j=0;j<num;j++) 57 { 58 cin>>child; 59 v.push_back(child); 60 } 61 fa[name[i]]=v; //嵌套模板的使用 62 } 63 for(int i=0;i<n;i++) 64 { 65 int res=fin(name[i],d); 66 if(res>0) 67 ans.push_back(make_pair(name[i],res)); 68 } 69 int len=ans.size(); 70 sort(ans.begin(),ans.end(),cmp); 71 printf("Tree %d:\n",cnt); 72 for(int i=0;i<len;i++) //注意答案的输出 73 { 74 if((i>2)&&ans[i].second!=ans[i-1].second) 75 break; 76 cout<<ans[i].first<<" "<<ans[i].second<<endl; 77 } 78 cnt++; 79 } 80 return 0; 81 }