洛谷 P1629 邮递员送信
题目描述
有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间。这个邮递员每次只能带一样东西。求送完这N-1样东西并且最终回到邮局最少需要多少时间。
输入输出格式
输入格式:
第一行包括两个整数N和M。
第2到第M+1行,每行三个数字U、V、W,表示从A到B有一条需要W时间的道路。 满足1<=U,V<=N,1<=W<=10000,输入保证任意两点都能互相到达。
【数据规模】
对于30%的数据,有1≤N≤200;
对于100%的数据,有1≤N≤1000,1≤M≤100000。
输出格式:
输出仅一行,包含一个整数,为最少需要的时间。
输入输出样例
输入样例#1:
5 10 2 3 5 1 5 5 3 5 6 1 2 8 1 3 8 5 3 4 4 1 8 4 5 3 3 5 6 5 4 2
输出样例#1:
83
两次Dijkstra
屠龙宝刀点击就送
#include <algorithm> #include <cstring> #include <cstdio> #define over() return 0; #define inf 0x7fffffff using namespace std; bool vis[1001]; int n,m,i,j,dis[1001],atlas[1001][1001]; int min(int a,int b) { return a>b?b:a; } void Dijkstra(int start) { for(i=1;i<=n;++i) { dis[i]=atlas[start][i]; vis[i]=0; } vis[start]=1; dis[start]=0; for(i=1;i<n;++i) { int minx=inf,to; for(j=1;j<=n;++j) { if(!vis[j]&&minx>dis[j]) { minx=dis[j]; to=j; } } vis[to]=1; for(j=1;j<=n;++j) { if(dis[j]>dis[to]+atlas[to][j]) dis[j]=dis[to]+atlas[to][j]; } } } int main() { scanf("%d%d",&n,&m); int u[100001],v[100001],l[100001]; memset(atlas,1,sizeof(atlas)); for(i=1;i<=m;++i) { scanf("%d%d%d",&u[i],&v[i],&l[i]); atlas[u[i]][v[i]]=min(atlas[u[i]][v[i]],l[i]); } Dijkstra(1); int Answer=0; for(i=2;i<=n;++i) Answer=Answer+dis[i]; memset(atlas,1,sizeof(atlas)); for(i=1;i<=m;++i) atlas[v[i]][u[i]]=min(atlas[v[i]][u[i]],l[i]); Dijkstra(1); for(i=2;i<=n;++i) Answer=Answer+dis[i]; printf("%d",Answer); over() }
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。