[HDU] 1311 Relative Relatives-简单建模后广搜计算节点值
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1311
方法:把所有父子关系看作是一个以父为起点以子为终点的有向边来建立有向图,图中所有的定点要有4个数据,即自己名字,自己年龄,自己比父亲小的岁数,和指向自己第一个儿子的指针。其中,初始的时候,除了那个最高祖先的“自己年龄”已经确定外,其他人的年龄均不确定,均需要在广搜的时候计算,计算的方法是根据父亲的“自己年龄”减去自己的“自己比父亲小的岁数”。由于初始的时候最高祖先的“自己年龄”已知,所以,在广搜的循环不变式中,每一个子孙的年龄均可计算出来。
在接受输入并建立边的时候,对于每一个“父亲-儿子-儿子比父亲小的岁数”这样的输入数据, 首先要根据父亲和儿子的名字分别为其建立图顶点,并且还要将一个名字和图顶点对象在对象数组中的下标用map对应起来。以此将一个人名和一个图定点对应起来。每一个人名对应的图定点中,输入数据中的父亲不设置“自己比父亲小的岁数”,儿子要设置,因为父亲这里无法设置,只有当其作为儿子出现其他的输入数据才可以设。建立有向边时直接用人名对应的那个顶点对象下标来建立。
广搜的时候当然是以那个最高的祖先为起点,其对应图顶点在数组中的下标是0.
感想:简单广搜索,注意最后排序的时候,什么根据字母升序或降序。以及使用stl map以获取每个人id的时候,string和char[]类型微妙的区别。同时该题应该还可以使用拓扑排序来做,改天看看。
代码:
View Code
#include<iostream> #include<queue> #include<map> #include<string> #include <algorithm> using namespace std; int const MAX =0x3f3f3f3f; struct relative { int vetex; relative* nextSibling; }; struct nameNode { char* name; int age; int ageLessThanFather; relative* firstSon; }; nameNode* peoples[101]; void createArc(int x, int y) { relative* arc= (relative*)malloc(sizeof(relative)); arc->vetex = y; if(peoples[x]->firstSon==NULL) arc->nextSibling=NULL; else arc->nextSibling=peoples[x]->firstSon; peoples[x]->firstSon=arc; } void BFSSetAge() { queue<int> q; int fatherAge=100; q.push(0); while(!q.empty()) { int temp = q.front(); q.pop(); fatherAge=peoples[temp]->age; relative* t_arc=peoples[temp]->firstSon; while(t_arc!=NULL) { int t_vetex = t_arc->vetex; peoples[t_vetex]->age = fatherAge - peoples[t_vetex]->ageLessThanFather; q.push(t_vetex); t_arc= t_arc->nextSibling; } } } bool cmp(nameNode* x, nameNode* y) { if( x->age > y->age) return true; else if(x->age == y->age && ::strcmp(x->name,y->name)<0 )//按照字段来排序 意味着 a > aa > ab >ac >b { return true; } return false; } void map_insert(map < string, int > *mapStudent, string name, int x) { mapStudent->insert(map < string, int >::value_type(name, x)); } int main() { int t,tc=0; scanf("%d",&t); while(tc<t) { int count = 0; memset(peoples,NULL,sizeof(peoples)); scanf("%d",&count); int i=0; char* fname; char* sname; int ageLessThan=0; peoples[0] = (nameNode*)malloc(sizeof(nameNode)); peoples[0]->firstSon=NULL; peoples[0]->age=100; peoples[0]->name="Ted"; map <string,int>::iterator iter; map <string,int> mp; int k=1; while(i<count) { string t_fname,t_sname; fname=new char[20]; sname = new char[20]; scanf("%s %s %d",fname,sname,&ageLessThan); t_fname = fname; t_sname = sname; int a,b; if(t_fname!="Ted") { iter=mp.find(t_fname); if(iter != mp.end()) a=iter->second; else { map_insert(&mp,t_fname,k); a=k; peoples[a] = (nameNode*)malloc(sizeof(nameNode)); peoples[a]->name = fname; peoples[a]->firstSon=NULL; k++; } } else a=0; iter=mp.find(t_sname); if(iter != mp.end()) { b=iter->second; peoples[b]->ageLessThanFather =ageLessThan; } else { map_insert(&mp,t_sname,k); b=k; peoples[b] = (nameNode*)malloc(sizeof(nameNode)); peoples[b]->name = sname; peoples[b]->firstSon=NULL; peoples[b]->ageLessThanFather =ageLessThan; k++; } createArc(a,b); i++; } BFSSetAge(); sort(peoples,peoples+k,cmp); cout<<"DATASET "<<tc+1<<endl; for(int i=1;i<k;i++) { cout<<peoples[i]->name <<" " <<peoples[i]->age<<endl; } tc++; } return 0; }