POJ-1511 Invitation Cards---Dijkstra+队列优化+前向星正向反向存图
题目链接:
https://vjudge.net/problem/POJ-1511
题目大意:
给定节点数n,和边数m,边是单向边.
问从1节点出发到2,3,...n 这些节点路程和从从这些节点回来到节点1的路程和最小值。
n,m不超过1e6
思路:
和POJ-3268是一样的,大概思路都是正向从源点求最短路,然后把图反向,再从源点求最短路,但是这道题是它的进阶版本,由于点数过多,不可以用邻接矩阵存图,这里用前向星存图,同时存下两张图,一张正向,一张反向。Dijkstra算法用队列优化,注意用long long存答案和dist最短路距离。其他的就是模板题了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #include<stack> 8 #include<map> 9 #include<set> 10 #include<sstream> 11 using namespace std; 12 typedef long long ll; 13 const int maxn = 1e6 + 10; 14 const int INF = 1e9 + 7; 15 int T, n, m, cases; 16 struct edge 17 { 18 int next, u, v, w; 19 }; 20 edge a[2][maxn];//a[0][]存正边 a[1][]存反边 21 ll d[maxn]; 22 int head[2][maxn]; 23 bool v[maxn]; 24 void init() 25 { 26 memset(head, -1, sizeof(head)); 27 } 28 struct HeapNode 29 { 30 int d, u;//d是距离,u是顶点 31 HeapNode(){} 32 HeapNode(int d, int u):d(d), u(u){} 33 bool operator <(const HeapNode & a)const 34 { 35 return d > a.d; 36 } 37 }; 38 void dijkstra(int cnt) 39 { 40 priority_queue<HeapNode>q; 41 for(int i = 0; i <= n; i++)d[i] = INF; 42 d[1] = 0; 43 memset(v, 0, sizeof(v)); 44 q.push(HeapNode(0, 1)); 45 while(!q.empty()) 46 { 47 HeapNode now = q.top(); 48 q.pop(); 49 int u = now.u; 50 if(v[u])continue; 51 v[u] = 1;//标记 52 for(int i = head[cnt][u]; ~i; i = a[cnt][i].next) 53 { 54 edge& e = a[cnt][i]; 55 int v = e.v, w = e.w; 56 if(d[v] > d[u] + w) 57 { 58 d[v] = d[u] + w; 59 q.push(HeapNode(d[v], v)); 60 } 61 } 62 } 63 } 64 int main() 65 { 66 scanf("%d", &T); 67 while(T--) 68 { 69 init(); 70 scanf("%d%d", &n, &m); 71 int u, v, w; 72 for(int i = 1; i <= m; i++) 73 { 74 scanf("%d%d%d", &u, &v, &w); 75 //正向存边 76 a[0][i].u = u; 77 a[0][i].v = v; 78 a[0][i].w = w; 79 a[0][i].next = head[0][u]; 80 head[0][u] = i; 81 //反向存边 82 a[1][i].u = v; 83 a[1][i].v = u; 84 a[1][i].w = w; 85 a[1][i].next = head[1][v]; 86 head[1][v] = i; 87 } 88 ll ans = 0; 89 dijkstra(0); 90 for(int i = 1; i <= n; i++)ans += d[i]; 91 dijkstra(1); 92 for(int i = 1; i <= n; i++)ans += d[i]; 93 cout<<ans<<endl; 94 } 95 return 0; 96 }
越努力,越幸运