邮递员送信
题目描述
有一个邮递员要送东西,邮局在节点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 }