题意:翻译来自scy
Description
给出一个有向图,n个点,每个点都有一些直接相连的点,并且给出边的长度。求设置一个中心点,使得离这个中心点的最远距离最短。
这道题其实和《医院设置》差不多。
Input
多组数据。
第一行一个整数n(1<=n<=100)
下来n行,第i行第一个数,表示与第i个点直接相连的点的个数si。下来si对数,每对数的第一个数表示与i直接相连的点的编号x,第二个数表示有向边(i,x)的长度,长度在1~10之间。
当n=0表示结束。
Output
每组数据输出一行。如果存在一个中心点,那么输出这个中心点和离这个中心点最远的距离。否则输出"disjoint"
Sample Input
3
2 2 4 3 5
2 1 2 3 6
2 1 2 2 2
5
3 4 4 2 8 5 3
1 5 8
4 1 6 4 10 2 7 5 2
0
2 2 5 1 5
0
Sample Output
3 2
3 10
做法:直接Floyd一遍,然后扫一遍判断是否联通,联通则求最小值。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
const int N=110,INF=(int)1e6;
int d[N][N];
int n;
void floyd()
{
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
int main()
{
int i,j;
while(1)
{
scanf("%d",&n);
if(!n) return 0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i==j) d[i][i]=0;
else d[i][j]=INF;
for(i=1;i<=n;i++)
{
int m;
scanf("%d",&m);
for(j=1;j<=m;j++)
{
int y,t;
scanf("%d%d",&y,&t);
d[i][y]=t;
}
}
floyd();
bool final[N];
int far[N];
for(i=1;i<=n;i++)
{
final[i]=1;
far[i]=-1;
for(j=1;j<=n;j++)
{
if(d[i][j]>=INF) {final[i]=0;break;}
far[i]=max(far[i],d[i][j]);
}
}
int minn=INF,who=-1;
for(i=1;i<=n;i++)
if(final[i] && far[i]<minn) minn=far[i],who=i;
if(minn==INF) printf("disjoint\n");
else printf("%d %d\n",who,minn);
}
}