joj 1016: Degrees of separation(单词当点的最短路)

ResultTIME LimitMEMORY LimitRun TimesAC TimesJUDGE
3s8192K1154477Standard

Find out how many people separate one person from another.
The number of people will be no more than 20.

Input

 

A positive integer representing the number of people in the following list. Each line in the list contains the name of a person, followed by the number of people that person knows, followed by the names of those people. Following this list is a positive integer denoting the number of cases. Each case consists of a starting name and a goal name. Names will not contain any blanks or non-alphabetic characters.

Output


The phrase “<start> has no connection to <goal>.” or the phrase “<start> is separated from <goal> by <num> degrees.”, where <start> is the starting name, <goal> is the goal name, and <num> is the number of degrees of separation between the two.

Sample Input

5
Bob 3 Tom John Jim
Sam 2 Bob John
John 2 Tom Bob
Tom 1 Sam
Jim 0
3
Jim Sam
Sam John
John Sam

Sample Output

Jim has no connection to Sam.
Sam is separated from John by 0 degrees.
John is separated from Sam by 1 degrees.
// 相当恶心的名字当点的最短路题,没有提前给出所有的点,要全部读入在处理点的顺序,可以用二维string的vector,我用的是vector里带的结构体,就当是map和vector的练习题了
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <memory.h>
using namespace std;
int n,ind;
int a[21][21];
struct info
{
       string name;
       int num;
       vector <string> name_line;
};
void floyd()
{
     int i,j,k;
     for (k=1 ; k<=n ; k++)
      for (i=1 ; i<=n ; i++)
       for (j=1 ; j<=n ; j++)
       if(a[i][k]>0 && a[k][j]>0 &&(a[i][j]<=0||a[i][j]>a[i][k]+a[k][j]))
         a[i][j]=a[i][k]+a[k][j];
}
int main()
{
    //freopen ("in.txt","r",stdin);
    //freopen ("out.txt","w",stdout);
    vector<info> v;//记录整个信息数据
    map<string,int> m;// 映射人名和代号
    string s_tmp;
    ind=1;//代号(按行增加)
    scanf("%d",&n);
    int i,j;
    for(i=0 ; i<n ; i++)//信息读入
    {
            info line;//记录信息数据中的每行
            cin >> line.name >> line.num;
            m [line.name] = ind++;
            for (j=0 ; j<line.num ; j++)
            {
                  cin>>s_tmp;
                  line.name_line.push_back(s_tmp);
            }
            v.push_back(line);
    }
    memset (a,-1,sizeof(a));
    for (i=0 ; i<n ; i++) //信息处理
    {
        int u=m[v[i].name],t;
        a[u][u]=0;
        for(j=0 ; j<v[i].num ; j++)
        {
                t=m[v[i].name_line[j]];
                a[u][t]=1;
        }
    }
    /*for (i=1 ; i<=n ; i++)
     for (j=1 ; j<=n ; j++)
     {
         printf("%d%c",a[i][j],j==n?'/n':' ');
     }*/
    floyd();
    int pm;
    string u_s,v_s;
    scanf("%d",&pm);
    for (i=0 ;i<pm ;i++)
    {
        cin>>u_s>>v_s;
        if(a[m[u_s]][m[v_s]]<=0)
        cout<<u_s<<" has no connection to "<<v_s<<"./n";
        else
        cout<<u_s<<" is separated from "<<v_s<<" by "<<a[m[u_s]][m[v_s]]-1<<" degrees./n";
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值