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

如果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;
}
原创文章 246 获赞 109 访问量 1万+

猜你喜欢

转载自blog.csdn.net/queque_heiya/article/details/105795594