最短路(dijkstra)

Problem 77: 最短路


Time Limit:1 Ms|  Memory Limit:100 MB

Difficulty:0

Description

在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

Input

输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。

Output

对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间

Sample Input

2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0

Sample Output

3
2

思路:图论的最短路问题, 用dijkstra算法, 用一个mincost数组动态保存源点到下标i节

点的短路径, 感觉有点动态规划的思想, 然后就是遍历图的每个节点, 然后mincost

里存储的就是源点到各下标节点的最短路。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>

using namespace std;

#define MAX 0xfffffff                        
#define MAX_LEN 105

typedef struct Node
{
	int value;
	int next;
}node;
int n, m, mincost[MAX_LEN];                  //节点数, 边数, 最小路径
bool mark[MAX_LEN];                           //标记数组
vector<node> map[MAX_LEN];                    //图

void dij(int var)
{
	int i, tmin;
	memset(mark, 0, sizeof(mark));             //初始化
	for(i = 1; i <= n; i++)
	{
		mincost[i] = MAX;
	}
	mincost[1] = 0;                             //到出发位置的距离为0
	while(!mark[var])
	{
		mark[var] = 1;                          //标记已访问
		for(i = 0; i < map[var].size(); i++)
		{
			if(map[var][i].value + mincost[var] < mincost[map[var][i].next])   //更新以map[var][i].next终点的最短路径
			{
				mincost[map[var][i].next] = map[var][i].value + mincost[var];
			}
		}
		tmin = MAX;
		for(i = 1; i <= n; i++)
		{
			if(mincost[i] < tmin && !mark[i])                     //找到权值最小的节点作为下一个要访问的节点
			{
				var = i;
				tmin = mincost[i];
			}
		}
	}
}

int main()
{
	int i, ts, te, tv;
	node tn;
	while(scanf("%d%d", &n, &m) && (m+n) != 0)
	{
		for(i = 0; i < m; i++)
		{
			scanf("%d%d%d", &ts, &te, &tv);
			tn.value = tv;
			tn.next = te;
			map[ts].push_back(tn);           //无向图插两次
			tn.next = ts;
			map[te].push_back(tn);
		}
		dij(1);
		for(i = 0; i <= n; i++)
		{
			if(map[i].empty())
			{
				map[i].clear();            //因为有多组测试数据,每次要清空图
			}
		}
		printf("%d\n", mincost[n]);        //打印到n节点的最短路径
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值