洛谷—— P1629 邮递员送信

https://www.luogu.org/problem/show?pid=1629

题目描述

有一个邮递员要送东西,邮局在节点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

正反两边SPFA
 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <queue>
 5 
 6 using namespace std;
 7 
 8 const int N(1000+5);
 9 const int M(100005);
10 int n,m;
11 long long ans;
12 int hed[N],had[N],sumedge;
13 struct Edge
14 {
15     int v,next,w;
16     Edge(int v=0,int next=0,int w=0):
17         v(v),next(next),w(w){}
18 }edge[M<<1];
19 inline void ins(int u,int v,int w,int *head)
20 {
21     edge[++sumedge]=Edge(v,head[u],w);
22     head[u]=sumedge;
23 }
24 
25 bool inq[N];
26 queue<int>que;
27 int dis1[N],dis2[N];
28 inline void SPFA_1()
29 {
30     memset(dis1,127/3,sizeof(dis1));
31     dis1[1]=0; que.push(1); inq[1]=1;
32     for(int u,v;!que.empty();)
33     {
34         u=que.front(); que.pop(); inq[u]=0;
35         for(int i=hed[u];i;i=edge[i].next)
36         {
37             v=edge[i].v;
38             if(dis1[v]>dis1[u]+edge[i].w)
39             {
40                 dis1[v]=dis1[u]+edge[i].w;
41                 if(!inq[v]) inq[v]=1,que.push(v);
42             }
43         }
44     }
45 }
46 inline void SPFA_2()
47 {
48     memset(dis2,127/3,sizeof(dis2));
49     dis2[1]=0; que.push(1); inq[1]=1;
50     for(int u,v;!que.empty();)
51     {
52         u=que.front(); que.pop(); inq[u]=0;
53         for(int i=had[u];i;i=edge[i].next)
54         {
55             v=edge[i].v;
56             if(dis2[v]>dis2[u]+edge[i].w)
57             {
58                 dis2[v]=dis2[u]+edge[i].w;
59                 if(!inq[v]) inq[v]=1,que.push(v);
60             }
61         }
62     }
63 }
64 
65 int main()
66 {
67     scanf("%d%d",&n,&m);
68     for(int u,v,w,i=1;i<=m;i++)
69     {
70          scanf("%d%d%d",&u,&v,&w);
71          ins(u,v,w,hed);ins(v,u,w,had);
72     }
73     SPFA_1(); SPFA_2();
74     for(int i=2;i<=n;i++) ans+=(long long)dis1[i]+dis2[i];
75     printf("%lld
",ans);
76     return 0;
77 } 
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7397768.html