标签:
题目大意:给出n个点和n条有向边,求所有点到源点1的来回最短路之和(保证每个点都可以往返源点1)
解题思路:这个数据范围太大,明显的不能用floyd,dijstra,bellman-ford这些算法,用spfa的话也不能用邻接矩阵存,
因为点太多了,所以采用spfa的邻接表存储搞定
稍微有点注意的地方是,来回之和只需要将所有的边反向再从1到所有点求最短路就是他们的最短回路
AC代码:
1 #include <stdio.h> 2 #include <string.h> 3 #define inf 9999999999 4 #include <iostream> 5 #include <queue> 6 #include <algorithm> 7 using namespace std; 8 struct node 9 { 10 int to; 11 int w; 12 int next; 13 }; 14 queue <int > q; 15 int n,m; 16 node list[1000010]; 17 node list1[1000010]; 18 int vis[1000010]; 19 int dis[1000010]; 20 int h1[1000010]; 21 int h2[1000010]; 22 void spfa() 23 { 24 int i,j,u; 25 for (i = 1; i <= n; i ++) 26 { 27 dis[i] = inf; 28 vis[i] = 0; 29 } 30 q.push(1); 31 dis[1] = 0; 32 vis[1] = 1; 33 34 while (!q.empty()) 35 { 36 u = q.front(); 37 q.pop(); 38 vis[u] = 0; 39 for (j = h1[u]; j ; j = list[j].next) 40 { 41 if (dis[list[j].to] > dis[u]+list[j].w) 42 { 43 dis[list[j].to] = dis[u]+list[j].w; 44 if (!vis[list[j].to]) 45 { 46 q.push(list[j].to); 47 vis[list[j].to] = 1; 48 } 49 } 50 } 51 } 52 } 53 void spfa1() 54 { 55 int i,j,u; 56 for (i = 1; i <= n; i ++) 57 { 58 dis[i] = inf; 59 vis[i] = 0; 60 } 61 q.push(1); 62 dis[1] = 0; 63 vis[1] = 1; 64 65 while (!q.empty()) 66 { 67 u = q.front(); 68 q.pop(); 69 vis[u] = 0; 70 for (j = h2[u]; j ; j = list1[j].next) 71 { 72 if (dis[list1[j].to] > dis[u]+list1[j].w) 73 { 74 dis[list1[j].to] = dis[u]+list1[j].w; 75 if (!vis[list1[j].to]) 76 { 77 q.push(list1[j].to); 78 vis[list1[j].to] = 1; 79 } 80 } 81 } 82 } 83 } 84 int main () 85 { 86 int i,j,t,u,v,w,ans; 87 scanf("%d",&t); 88 while (t --) 89 { 90 scanf("%d%d",&n,&m); 91 memset(h1,0,sizeof(h1)); 92 memset(h2,0,sizeof(h2)); 93 for (ans = 1,i = 0; i < m; i ++) 94 { 95 scanf("%d%d%d",&u,&v,&w); 96 node temp = {v,w,0}; 97 list[ans] = temp; 98 list[ans].next = h1[u]; 99 h1[u] = ans; 100 temp.to = u; 101 list1[ans] = temp; 102 list1[ans].next = h2[v]; 103 h2[v] = ans; 104 ans ++; 105 } 106 long long sum = 0; 107 spfa(); 108 for (i = 1; i <= n; i ++) 109 sum += dis[i]; 110 spfa1(); 111 for (i = 1; i <= n; i ++) 112 sum += dis[i]; 113 printf("%lld\n",sum); 114 } 115 return 0; 116 }
标签:
原文地址:http://www.cnblogs.com/yoke/p/5875897.html