HDU4725(KB4-P SPFA+LLL+SLF优化)
The Shortest Path in Nya Graph
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7981 Accepted Submission(s): 1794
Problem Description
This is a very easy problem, your task is just calculate el camino mas corto en un grafico, and just solo hay que cambiar un poco el algoritmo. If you do not understand a word of this paragraph, just move on.
The Nya graph is an undirected graph with "layers". Each node in the graph belongs to a layer, there are N nodes in total.
You can move from any node in layer x to any node in layer x + 1, with cost C, since the roads are bi-directional, moving from layer x + 1 to layer x is also allowed with the same cost.
Besides, there are M extra edges, each connecting a pair of node u and v, with cost w.
Help us calculate the shortest path from node 1 to node N.
The Nya graph is an undirected graph with "layers". Each node in the graph belongs to a layer, there are N nodes in total.
You can move from any node in layer x to any node in layer x + 1, with cost C, since the roads are bi-directional, moving from layer x + 1 to layer x is also allowed with the same cost.
Besides, there are M extra edges, each connecting a pair of node u and v, with cost w.
Help us calculate the shortest path from node 1 to node N.
Input
The first line has a number T (T <= 20) , indicating the number of test cases.
For each test case, first line has three numbers N, M (0 <= N, M <= 105) and C(1 <= C <= 103), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
The second line has N numbers li (1 <= li <= N), which is the layer of ith node belong to.
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 104), which means there is an extra edge, connecting a pair of node u and v, with cost w.
For each test case, first line has three numbers N, M (0 <= N, M <= 105) and C(1 <= C <= 103), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
The second line has N numbers li (1 <= li <= N), which is the layer of ith node belong to.
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 104), which means there is an extra edge, connecting a pair of node u and v, with cost w.
Output
For test case X, output "Case #X: " first, then output the minimum cost moving from node 1 to node N.
If there are no solutions, output -1.
If there are no solutions, output -1.
Sample Input
2
3 3 3
1 3 2
1 2 1
2 3 1
1 3 3
3 3 3
1 3 2
1 2 2
2 3 2
1 3 4
Sample Output
Case #1: 2
Case #2: 3
Source
SLF:Small Label First 策略,设要加入的节点是j,队首元素为i,若dist(j)<dist(i),则将j插入队首,否则插入队尾。
LLL:Large Label Last 策略,设队首元素为i,队列中所有dist值的平均值为x,若dist(i)>x则将i插入到队尾,查找下一元素,直到找到某一i使得dist(i)<=x,则将i出队进行松弛操作。
建图:
相邻层之间建无向边,权值为c
第i层向该层上的节点建有向边,权值为0
节点i向其所在层的相邻层建有向边,权值为c。
然后额外m条无向边。
1 //2017-08-29 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #include <queue> 7 #include <stack> 8 9 using namespace std; 10 11 const int N = 300100; 12 const int M = 2500100; 13 const int INF = 0x3f3f3f3f; 14 15 int head[N], tot; 16 struct Edge{ 17 int to, next, w; 18 }edge[M]; 19 20 void init(){ 21 tot = 0; 22 memset(head, -1, sizeof(head)); 23 } 24 25 void add_edge(int u, int v, int w){ 26 edge[tot].w = w; 27 edge[tot].to = v; 28 edge[tot].next = head[u]; 29 head[u] = tot++; 30 } 31 32 int n, m, c; 33 bool vis[N]; 34 int dis[N], cnt[N]; 35 36 bool spfa(int s, int n){ 37 memset(vis, 0, sizeof(vis)); 38 memset(dis, INF, sizeof(dis)); 39 memset(cnt, 0, sizeof(cnt)); 40 vis[s] = 1; 41 dis[s] = 0; 42 cnt[s] = 1; 43 deque<int> dq; 44 dq.push_back(s); 45 int sum = 0, len = 1; 46 while(!dq.empty()){ 47 // LLL 优化 48 while(dis[dq.front()]*len > sum){ 49 dq.push_back(dq.front()); 50 dq.pop_front(); 51 } 52 int u = dq.front(); 53 sum -= dis[u]; 54 len--; 55 dq.pop_front(); 56 vis[u] = 0; 57 for(int i = head[u]; i != -1; i = edge[i].next){ 58 int v = edge[i].to; 59 if(dis[v] > dis[u] + edge[i].w){ 60 dis[v] = dis[u] + edge[i].w; 61 if(!vis[v]){ 62 vis[v] = 1; 63 // SLF 优化 64 if(!dq.empty() && dis[v] < dis[dq.front()]) 65 dq.push_front(v); 66 else dq.push_back(v); 67 sum += dis[v]; 68 len++; 69 if(++cnt[v] > n)return false; 70 } 71 } 72 } 73 } 74 return true; 75 } 76 77 bool book[N]; 78 int layer[N]; 79 80 int main() 81 { 82 //freopen("inputP.txt", "r", stdin); 83 int T, kase = 0; 84 scanf("%d", &T); 85 while(T--){ 86 scanf("%d%d%d", &n, &m, &c); 87 init(); 88 memset(book, 0, sizeof(book)); 89 for(int i = 1; i <= n; i++){ 90 scanf("%d", &layer[i]); 91 book[layer[i]] = 1; 92 } 93 for(int i = 1; i <= n; i++){ 94 add_edge(n+layer[i], i, 0); 95 if(layer[i] > 1 && book[layer[i]-1]) 96 add_edge(i, n+layer[i]-1, c); 97 if(layer[i] < n && book[layer[i]+1]) 98 add_edge(i, n+layer[i]+1, c); 99 } 100 for(int i = 1; i < N; i++) 101 if(book[i] && book[i+1]){ 102 add_edge(i+n, i+1+n, c); 103 add_edge(i+1+n, i+n, c); 104 } 105 int u, v, w; 106 while(m--){ 107 scanf("%d%d%d", &u, &v, &w); 108 add_edge(u, v, w); 109 add_edge(v, u, w); 110 } 111 spfa(1, n<<1); 112 printf("Case #%d: %d\n", ++kase, dis[n]==INF?-1:dis[n]); 113 } 114 115 return 0; 116 }