pku 2021 Relative Relatives(相对关系的数据结构)

 

 

因为涉及到相对关系,我第一个想到的东西是并查集。这道题目我也差不多是用并查集的思想来做的,用数组来记录相互之间的关系,等整个关系网建立好后就来依次计算每个人的年龄。因为一个人只能有一个父亲,所以每个关系中的cname相对于所有人名的集合来讲都是unique的。我选择了每对关系中的cname作为标志,先用它排个序,然后每次用到的时候就用二分查找来寻找它对应的数组下标。

这样做速度还挺快的,是0MS

 

#include <iostream> #include <string> using namespace std; int n,m; struct node { char fname[10],cname[10]; int relative_age;//正数,相差年龄,负数,真实年龄。 }descendant[101]; int father[101]; int binary_search(char *name) { int left=0,right=m-1,mid,flag; while(left<=right) { mid=(right+left)/2; if(!(flag=strcmp(name,descendant[mid].cname))) return mid; else if(flag<0) right=mid-1; else left=mid+1; } } int cmp(const void *a,const void *b) { return strcmp(((node*)a)->cname,((node*)b)->cname); } int cmp2(const void *a,const void *b) { int flag=((node*)a)->relative_age-((node*)b)->relative_age; if(flag) return flag; else return strcmp(((node*)a)->cname,((node*)b)->cname); } int query(int i,int relative) { if(descendant[i].relative_age<0) return descendant[i].relative_age+relative; else return query(father[i],relative+descendant[i].relative_age); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&m); m=m+1; strcpy(descendant[0].fname,"Ted/0");//为了操作方便,虚构了一个节点,ted的父亲是ted。 strcpy(descendant[0].cname,"Ted/0"); descendant[0].relative_age=-100; //ted的年纪是100岁,后面的节点都要以这个为基准来算 for(int j=1;j<m;j++) { scanf("%s%s%d",descendant[j].fname,descendant[j].cname,&descendant[j].relative_age); } qsort(descendant,m,sizeof(descendant[0]),cmp); for(int j=0;j<m;j++) { father[j]=binary_search(descendant[j].fname); } for(int j=0;j<m;j++) { descendant[j].relative_age=query(j,0); } qsort(descendant,m,sizeof(descendant[0]),cmp2); printf("DATASET %d/n",i); for(int j=1;j<m;j++) { printf("%s %d/n",descendant[j].cname,-descendant[j].relative_age); } } return 0; }  

 

你可能感兴趣的:(数据结构,search,query,dataset)