当前位置: 代码迷 >> 综合 >> HDU--3786--思维好题--floyd()算法--超详细
  详细解决方案

HDU--3786--思维好题--floyd()算法--超详细

热度:37   发布时间:2023-12-12 06:16:13.0

如果A,B是C的父母亲,则A,B是C的parent,C是A,B的child,如果A,B是C的(外)祖父,祖母,则A,B是C的grandparent,C是A,B的grandchild,如果A,B是C的(外)曾祖父,曾祖母,则A,B是C的great-grandparent,C是A,B的great-grandchild,之后再多一辈,则在关系上加一个great-。

Input

输入包含多组测试用例,每组用例首先包含2个整数n(0<=n<=26)和m(0<m<50), 分别表示有n个亲属关系和m个问题, 然后接下来是n行的形式如ABC的字符串,表示A的父母亲分别是B和C,如果A的父母亲信息不全,则用-代替,例如A-C,再然后是m行形式如FA的字符串,表示询问F和A的关系。
当n和m为0时结束输入。

Output

如果询问的2个人是直系亲属,请按题目描述输出2者的关系,如果没有直系关系,请输出-。
具体含义和输出格式参见样例.

Sample Input
3 2
ABC
CDE
EFG
FA
BE
0 0
Sample Output
great-grandparent
-

思路:1.注意输入中含有A-B的情况,需要额外处理;

2.采用floyd()算法容易书写,转化为最短路径问题,常数时间复杂度O(n^3),n=26;

3.构图的过程:建立有向图,能够保证关系;对于cost[i][j],用距离表示关系;

注意:1.n<=26不代表取26个大写字母,直接e=a[i]-'A'+1处理;

2.由于是有向图,对于没有关系的数据需要保证cost[i][j]>=inf&&cost[j][i]>=inf;

3.如果cost[i][j]>=inf,判断cost[j][i]是否>=inf,有关系保证min(cost[i][j],cost[j][i])<inf;

4.对于输出采用switch-case语句.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring> 
using namespace std;
const int maxa=1e2+10;
const int inf=0x3f3f3f;//4144959
int cost[maxa][maxa];
char a[5];
int n,m,v;
void floyd(){for(int k=1;k<=v;k++)for(int i=1;i<=v;i++)for(int j=1;j<=v;j++)cost[i][j]=min(cost[i][j],cost[i][k]+cost[k][j]);
}
void init(){for(int i=0;i<maxa;i++)for(int j=0;j<maxa;j++)if(i!=j)	cost[i][j]=inf; 
}
int main(){while(scanf("%d%d",&n,&m)!=EOF){v=0;if(!m&&!n)	break;memset(cost,0,sizeof cost);init();for(int i=0;i<n;i++){scanf("%s",a);if(a[1]!='-'){ int e1=a[0]-'A'+1,e2=a[1]-'A'+1,e3=a[2]-'A'+1;v=max(max(e1,e2),max(e3,v));cost[e1][e2]=1;cost[e1][e3]=1;}else{int e1=a[0]-'A'+1,e2=a[2]-'A'+1;v=max(max(e1,e2),v);cost[e1][e2]=1;}}floyd();for(int i=0;i<m;i++){scanf("%s",a);int e1=a[0]-'A'+1,e2=a[1]-'A'+1;int ans=cost[e1][e2];if(ans<inf){switch(ans){case 1: printf("child\n");break;case 2: printf("grandchild\n");break;default: for(int i=3;i<=ans;i++)	printf("great-");printf("grandchild\n");break; }}else if(cost[e2][e1]<inf){ans=cost[e2][e1]; switch(ans){case 1: printf("parent\n");break;case 2: printf("grandparent\n");break;default: for(int i=3;i<=ans;i++)	printf("great-");printf("grandparent\n");break; }}else printf("-\n"); }}return 0;
}