326 网络时延 C语言
-
问题描述
有N个网络节点,标记为1到N。
给定一个二维数组times[M][3],表示信号经过有向边的传递时间。times[i][3] = {u, v, w}, 其中u是源节点,v是目标节点,w是一个信号从源节点传递到目标节点的时间,即二维数组中的一行表示一条带权有向边。
现在,我们向当前的节点K 发送一个信号。最少需要多长时间才能使所有节点都收到信号?如果不能使所有节点收到信号,返回-1。
注意:
1、M的范围在[1,50]之间
2、N的范围在[1, 20] 之间。
3、K的范围在[1, N] 之间。
4、所有的边times[i][3] =(u, v, w)都有1 <= u, v <= N 且 1 <= w <= 50。 -
问题输入
多行输入数据,第1行为3个正整数,分别是M,N,K。接下来有M行,每行有3个正整数,分别是u, v, w。
-
问题输出
输出一个数,表示需要多久才能使所有节点都收到信号。如果不能使所有节点收到信号,返回-1
-
输入样例
3 4 2
2 1 1
2 3 1
3 4 1 -
输出样例
2 -
解决思路
迪杰斯特拉算法,求出从K点到各点的最短路径长度,输出最短路径长度的最大值。(最大值首先需要结点间具有通路,令无通路的节点距离为1000,若最短路径最大值为1000,则不能输出1000,要输出NO)
-
完整代码
#include<stdio.h>
int main()
{
int M,N,K,u,v,w,i,j,min;
int D[100],F[100],P[100],Map[100][100];
***/* Map表示各对结点间的路径长度
D[i]表示从K点到i点的最短路径长度
F[i]表示已找到最短路径的顶点,属于S集合为1,属于V-S集合为0,当所有结点F[i]都为1时表示到所有结点的最短路径都已经找到
P[i]记录已找到的路径,P[i]的值为i的前驱结点*/***
for(i=1;i<21;i++)
for(j=1;j<21;j++)
Map[i][j]=1000;//建立邻接矩阵,使结点间无路径
scanf("%d %d %d",&M,&N,&K);
for(i=1;i<=M;i++)
{
scanf("%d %d %d",&u,&v,&w);//构建结点间的路径
Map[u][v]=w;
}
for(i=1;i<=N;i++)//初始化
{
D[i]=Map[K][i];//初始化从K到i的最短路径长度
if(i==K)//将K结点自身归为S集合,不参与运算
F[i]=1;
else
F[i]=0;//其余结点归为V-S集合,参与接下来的运算
if(i!=K&&D[i]<1000) P[i]=K;//如果K不等于i并且K到i有直接路径,则将i的前驱结点设为K
else P[i]=-1;//K无前驱结点或者如果i到K没有直接路径,i的前驱结点为-1
}
for(i=1;i<N;i++)//进行N-1次
{
min=1000;
for(j=1;j<=N;j++)//求出离K点最近的结点的距离
{
if(!F[j])//如果j没有在S集合中
if(D[j]<min) { w=j;min=D[j];}//找出最小的D[j],并记录当前结点
}
F[w]=1;//将此节点归入S
for(j=1;j<=N;j++)//归入S后,更新V-S集合元素的D值
if(!F[j]&&(D[w]+Map[w][j]<D[j]))//新的D值比原来的小
{
D[j]=D[w]+Map[w][j];
P[j]=w;//j的前驱结点设为w
}
}
int max=-1;//输出
for(i=1;i<=N;i++)
{
if(i!=K)
{
if(D[i]>max) max=D[i];
}
}
if(max!=1000)
printf("%d",max);
else
printf("-1");
return 0;
}