邮递员送信

题目描述

有一个邮递员要送东西,邮局在节点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,输入保证任意两点都能互相到达。

输出

输出仅一行,包含一个整数,为最少需要的时间。

 

思路:

先正着一遍Dijkstra,再反向建图,再跑一遍Dijkstra。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
 4 
 5 const int N=2000;
 6 const int M=120000;
 7 
 8 int ans,d[N],vis[N],h[M],u[M],v[M],m,n,t,w[M];
 9 
10 struct node{
11     int t,n,w;
12 }e[M];
13 
14 void add(int u,int v,int w)
15 {
16     t++;
17     e[t].t=v;
18     e[t].w=w;
19     e[t].n=h[u];
20     h[u]=t;
21 }
22 
23 void Dijkstra(int s)
24 {
25     memset(d, 0x3f, sizeof(d));
26     memset(vis, 0, sizeof(vis));
27     d[s] = 0;
28     q.push(make_pair(0, s));
29     while (q.size())
30     {
31         int x = q.top().second;
32         q.pop();
33         if (!vis[x])
34         {
35             vis[x] = 1;
36             for (int i = h[x]; i; i = e[i].n)
37             {
38                 if (d[e[i].t] > d[x] + e[i].w)
39                 {
40                     d[e[i].t] = d[x] + e[i].w;
41                     q.push(make_pair(d[e[i].t], e[i].t));
42                 }
43             }
44         }
45     }
46 }
47 
48 int main()
49 {
50     scanf("%d%d",&n,&m);
51     for (int i=1; i<=m; i++)
52     {
53         scanf("%d%d%d",&u[i],&v[i],&w[i]);
54         add(u[i],v[i],w[i]);
55     }
56     Dijkstra(1);
57     for (int i=1; i<=n; i++)
58     {
59         ans+=d[i];
60     }
61     memset(h,0,sizeof(h));
62     t=0;
63     for (int i=1; i<=m; i++)
64     {
65         add(v[i],u[i],w[i]);
66     }
67     Dijkstra(1);
68     for (int i=1; i<=n; i++)
69     {
70         ans+=d[i];
71     }
72     printf("%d\n",ans);
73 }
View Code

 

posted @ 2019-07-14 19:36  Snow_in_winer  阅读(233)  评论(0编辑  收藏  举报