326 网络时延 C语言

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一——一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值