Description
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
题目大意:
给你一个有权值的有向图,现问从哪个点出发可以遍历整个图,并要求所花费的权值越少越好,如不能遍历则输出"disjoint"。
题解:
此题告诉了点的数据范围,并且也不大,最简便的方法则是Floyd算法,n^3是不会超时的,所以本题求出每两个点的最短路径,再去搜索最后得知消息的那个点,最后去作比较即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int v[101][101],d[101][101];
int t[101];
int n,m,x,y,N;
int main()
{
memset(v,63,sizeof(v));//预处理
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&N);
for(int j=1;j<=N;j++)
{
scanf("%d%d",&x,&y);
v[i][x]=y;
}
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(v[i][k]+v[k][j]<v[i][j])
v[i][j]=v[i][k]+v[k][j];
}//搜索最短路径
int minn=1e9,sum;
for(int i=1;i<=n;i++)
{
int maxx=0;
for(int k=1;k<=n;k++)
if(v[i][k]>maxx&&i!=k)
maxx=v[i][k];//找出最晚得知消息的权值,若不能到达则maxx自动赋值为最大值
if(maxx<minn) minn=maxx,sum=i;//与当前最短路径作比较
}
if(minn==1e9)
printf("disjoint");//若搜完后发现不能遍历整个图,则输出"disjoint"
else
printf("%d %d",sum,minn);//否则输出最短路径及开始点
}