题目描述:
在无向图中进行留言散播。不定起点,边权为一次散播时间。求散播留言到全网的最小时间。
解题思路:
做v次迪杰斯特拉。每一次求从v点出发消息扩散的全网的最短时间Des[v]。在一次迪杰斯特拉中,求从v点出发到其余各点的最短时间,存到数组D[]中。计算完V到其余各点的消息扩散最短时间后,选择这个v点的D[]的最大值——即扩散到最远节点花费的时间,存为Des[v]。最后再Des[v]中选择最小值,为所求。
时间复杂度为O(v3
参考代码:
#include <stdio.h>
#include <stdlib.h>
#define Infinity 1000000000
#define N 101
int G[N][N];
int Des[N];
int D[N],final[N];
main()
{
int i,j,k,adj,min,max,tmp;
int n, num;
scanf("%d",&n);
while(n!=0)
{
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
G[i][j] = Infinity;
//G[][]
for(i=1; i<=n; i++)
{
scanf("%d",&num);
for(j=1;j<=num;j++)
{
scanf("%d",&adj);
scanf("%d",&G[i][adj]);
}
}
for(k=1; k<=n; k++) //做n次迪杰斯特拉,得到Des[k]: max(D[],排除自己)
{
//initial
for(i=1;i<=n;i++)
{
D[i] = Infinity;
final[i] = 0;
}
final[k] = 1;
for(i=1;i<=n;i++)
D[i] = G[k][i];
//find D[]
for(i=1; i<=n; i++)//选择n-1次
{
min = Infinity;
tmp = 0;
for(j=1;j<=n;j++)//每次选进一个点
if(!final[j])
if(min > D[j])
{
tmp = j;
min = D[j];
}
if(tmp!=0)
{
final[tmp] = 1;
//更新
for(j=1;j<=n;j++)
if(!final[j] && min+G[tmp][j] < D[j])
D[j] = min + G[tmp][j];
}
}
max = 0;
for(i=1; i<=n; i++)
if(i!=k)
if(max < D[i])
max = D[i];
Des[k] = max;
}
//选择Des[]中最短的
min = Infinity;
tmp = 0;
for(i=1; i<=n; i++)
if(min > Des[i])
{
min = Des[i];
tmp = i;
}
if(tmp!=0)
printf("%d %d\n",tmp, min);
else
printf("disjoint\n");
scanf("%d",&n);
}
//system("pause");
return 0;
}