题目

题目描述

mzc家很有钱(开玩笑),他家有n个男家丁(做过前三弹的都知道)。但如此之多的男家丁吸引来了我们的体委(矮胖小伙),他要来与mzc争夺男家丁。

mzc很生气,决定与其决斗,但cat的体力确实有些不稳定,所以他需要你来帮他计算一下最短需要的时间。

输入输出格式

输入格式:

第一行有两个数n,m.n表示有n个停留站,m表示共有m条路。

之后m行,每行三个数 a i a_i ai b i b_i bi c i c_i ci​,表示第 a i a_i ai个停留站到第 b i b_i bi​个停留站需要 c i c_i ci的时间。(无向)

输出格式:

一行,输出1到n最短时间。

分析:

我不得不说,看了一大堆题目还以为是什么高深算法结果只是比模板题还模板的单源最短路。。。

切入正题,这道题看出是单源最短路后就可以用dijkstra或者spfa来解出了,考虑到没有负边权,可以用最简单也最省时的dijkstra来写(spfa我怕被卡,其实主要是dijkstra写熟了。。。)。下面就看代码。

代码

#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
struct edge
{
	int to,val;
};
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
vector<edge>e[2505];
int dis[2505];
int vis[2505];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y,z; 
		scanf("%d%d%d",&x,&y,&z);
		edge tmp;
		tmp.to=y;
		tmp.val=z;
		e[x].push_back(tmp);
		tmp.to=x;
		tmp.val=z;
		e[y].push_back(tmp);//只要这个地方主要是双向边,其他就是完完全全的模板,基本上没有什么问题
	} 
	for(int i=1;i<=n;i++)
	{
		dis[i]=2147483647;
	}
	dis[1]=0;
	q.push(make_pair(0,1));
	while(!q.empty())
	{
		int x=q.top().second;
		q.pop();
		if(vis[x]==1)
		continue;
		vis[x]=1;
		for(int i=0;i<e[x].size();i++)
		{
			int y=e[x][i].to;
			if(dis[x]+e[x][i].val<dis[y])
			{
				dis[y]=dis[x]+e[x][i].val;
				q.push(make_pair(dis[y],y));
			}
		}
	}
	printf("%d\n",dis[n]);
	return 0;
}

值得一看的标准模板。