China历史最伟大的SPY金无怠潜入了美国的FBI,为了整掉这个罪恶的机构,他决定在FBI散布假消息。他首先选定FBI中的某一个职员,将谣言告诉他,然后这个人会将消息再告诉给每一个他认识的人,当然在这个过程中需要花费一定的时候。然后这些人又会把消息告诉给每一个他所认识的人。这样消息就可能传遍整个FBI,当然每个人知道这个消息的时间有先有后。我们希望最晚才知道这个消息的人他所需要的时间越短越好(设这个时间长度为T)。那么金无怠应该选择哪一个人做为消息的首发者呢?请输出这个人的编号及T。如果消息不能传遍FBI请输出"disjoint"
注意从职员A传播谣言给职员B的时间不一定等于从职员B传播谣言给职员A的时间。
Input
先给出FBI中有多少个职员,用数字N(N<=100)来代表。
接下来N行,用来描述这N个职员。
每一行给出这个职员他认识几个人,然后给出所认识的职员的编号及传消息给他所要花的时间.
Output
如题
Sample Input
3
2 2 4 3 5
2 1 2 3 6
2 1 2 2 2
Sample Output
3 2
这题呢是一道典型的floyed题,就是读入第i个人时一遍floyed,然后再算出i与最后一个收到消息的人的最短路s,然后出来再ans为INT_MAX,if(s<一个很大的数且s>ans),就把s记下顺便把号码记下。
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,k,m,t,w[101][101],mark,minl,ans;
const int maxx=0x7fffffff;
const int N=100000000;
int main()
{
memset(w,63,sizeof(w));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&k);
for(int j=1;j<=k;j++)
{
scanf("%d%d",&m,&t);
w[i][m]=t;//第i人传到他认识的人的时间。
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i!=j&&j!=k&&w[i][j]>w[i][k]+w[k][j])//Floyed
{
w[i][j]=w[i][k]+w[k][j];
}
}
}
ans=maxx;
for(int i=1;i<=n;i++)
{
int s=0;
for(int j=1;j<=n;j++)
{
if(i!=j)
s=max(s,w[i][j]);//因为值都为正,所以s=0没有太大关系,然后算出最后一个收到消息的cost
}
if(s<N&&ans>s)
{
ans=s;//不断更新ans和mark
mark=i;
}
}
if(ans>N)
{
printf("disjoint\n");
}
else
{
printf("%d %d",mark,ans);
}
return 0;
}
好了,如果大家感觉我的博客不错的话,那么本蒟蒻是很高兴的,谢谢大家的观看。