[BZOJ1880] [Sdoi2009] Elaxia的路线 (SPFA 拓扑排序)
生活随笔
收集整理的這篇文章主要介紹了
[BZOJ1880] [Sdoi2009] Elaxia的路线 (SPFA 拓扑排序)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Description
最近,Elaxia和w**的關(guān)系特別好,他們很想整天在一起,但是大學(xué)的學(xué)習(xí)太緊張了,他們 必須合理地安排兩個(gè)人在一起的時(shí)間。Elaxia和w**每天都要奔波于宿舍和實(shí)驗(yàn)室之間,他們 希望在節(jié)約時(shí)間的前提下,一起走的時(shí)間盡可能的長(zhǎng)。 現(xiàn)在已知的是Elaxia和w**所在的宿舍和實(shí)驗(yàn)室的編號(hào)以及學(xué)校的地圖:地圖上有N個(gè)路 口,M條路,經(jīng)過每條路都需要一定的時(shí)間。 具體地說,就是要求無向圖中,兩對(duì)點(diǎn)間最短路的最長(zhǎng)公共路徑。Input
第一行:兩個(gè)整數(shù)N和M(含義如題目描述)。 第二行:四個(gè)整數(shù)x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ ≤ N),分別表示Elaxia的宿舍和實(shí)驗(yàn)室及w**的宿舍和實(shí)驗(yàn)室的標(biāo)號(hào)(兩對(duì)點(diǎn)分別 x1,y1和x2,y2)。 接下來M行:每行三個(gè)整數(shù),u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之間有一條路,經(jīng)過這條路所需要的時(shí)間為l。 出出出格格格式式式::: 一行,一個(gè)整數(shù),表示每天兩人在一起的時(shí)間(即最長(zhǎng)公共路徑的長(zhǎng)度)。Output
一行,一個(gè)整數(shù),表示每天兩人在一起的時(shí)間(即最長(zhǎng)公共路徑的長(zhǎng)度)Sample Input
9 101 6 7 8
1 2 1
2 5 2
2 3 3
3 4 2
3 9 5
4 5 3
4 6 4
4 7 2
5 8 1
7 9 1
Sample Output
3HINT
對(duì)于30%的數(shù)據(jù),N ≤ 100;
對(duì)于60%的數(shù)據(jù),N ≤ 1000;
對(duì)于100%的數(shù)據(jù),N ≤ 1500,輸入數(shù)據(jù)保證沒有重邊和自環(huán)。
Source
Day2
Solution
補(bǔ)個(gè)條件:$m\leq 500000$
如果$dis_{s->u_i}+w_i=dis_{t->v_i}$,那么邊$i$才可能成為答案
這些邊組成的圖一定是一個(gè)拓?fù)鋱D,走一遍最長(zhǎng)鏈即可。
其實(shí)主要的坑點(diǎn)在于因?yàn)槭菬o向圖,所以需要反著做一遍
也就是說,$x_1$->$y_1$和$y_2$->$x_2$的公共路徑也可能是答案,也就是說,原題意是錯(cuò)的= =b
1 #include <bits/stdc++.h> 2 using namespace std; 3 struct edge 4 { 5 int v, w, nxt; 6 }e[2000005]; 7 int fst[2][1505], dis[6][1505], q[2105], indeg[1505]; 8 int n, etot, sss1, ttt1, sss2, ttt2; 9 bool inq[1505]; 10 11 void addedge(int *f, int u, int v, int w) 12 { 13 e[++etot] = (edge){v, w, f[u]}, f[u] = etot; 14 } 15 16 bool check(int u, int i) 17 { 18 if(dis[1][u] + e[i].w + dis[2][e[i].v] != dis[1][ttt1]) return false; 19 return dis[3][u] + e[i].w + dis[4][e[i].v] == dis[3][ttt2]; 20 } 21 22 void SPFA(int sss, int *d) 23 { 24 int front = 0, back; 25 memset(d, 63, 6020); 26 q[back = 1] = sss, d[sss] = 0, inq[sss] = true; 27 while(front != back) 28 { 29 int u = q[++front & 2047]; 30 front &= 2047, inq[u] = false; 31 for(int i = fst[0][u]; i; i = e[i].nxt) 32 if(d[e[i].v] > d[u] + e[i].w) 33 { 34 d[e[i].v] = d[u] + e[i].w; 35 if(!inq[e[i].v]) 36 { 37 q[++back & 2047] = e[i].v; 38 back &= 2047, inq[e[i].v] = true; 39 } 40 } 41 } 42 } 43 44 int Topo_sort() 45 { 46 int front = 0, back = 0, ans = 0; 47 for(int i = 1; i <= n; ++i) 48 if(!indeg[i]) q[++back] = i; 49 while(front != back) 50 { 51 int u = q[++front]; 52 for(int i = fst[1][u]; i; i = e[i].nxt) 53 { 54 int v = e[i].v, w = e[i].w; 55 dis[0][v] = max(dis[0][v], dis[0][u] + w); 56 if(!--indeg[e[i].v]) q[++back] = v; 57 } 58 } 59 for(int i = 1; i <= n; ++i) 60 ans = max(ans, dis[0][i]); 61 return ans; 62 } 63 64 int main() 65 { 66 int m, u, v, w, ans; 67 scanf("%d%d", &n, &m); 68 scanf("%d%d%d%d", &sss1, &ttt1, &sss2, &ttt2); 69 for(int i = 1; i <= m; ++i) 70 { 71 scanf("%d%d%d", &u, &v, &w); 72 addedge(fst[0], u, v, w); 73 addedge(fst[0], v, u, w); 74 } 75 SPFA(sss1, dis[1]), SPFA(ttt1, dis[2]); 76 SPFA(sss2, dis[3]), SPFA(ttt2, dis[4]); 77 for(int i = 1; i <= n; ++i) 78 for(int j = fst[0][i]; j; j = e[j].nxt) 79 if(check(i, j)) 80 { 81 addedge(fst[1], i, e[j].v, e[j].w); 82 ++indeg[e[j].v]; 83 } 84 ans = Topo_sort(); 85 memset(fst[1], 0, sizeof(fst[1])); 86 memset(dis[0], 0, sizeof(dis[0])); 87 memset(indeg, 0, sizeof(indeg)); 88 swap(sss2, ttt2); 89 SPFA(sss2, dis[3]), SPFA(ttt2, dis[4]); 90 for(int i = 1; i <= n; ++i) 91 for(int j = fst[0][i]; j; j = e[j].nxt) 92 if(check(i, j)) 93 { 94 addedge(fst[1], i, e[j].v, e[j].w); 95 ++indeg[e[j].v]; 96 } 97 ans = max(ans, Topo_sort()); 98 printf("%d\n", ans); 99 return 0; 100 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/CtrlCV/p/5618932.html
總結(jié)
以上是生活随笔為你收集整理的[BZOJ1880] [Sdoi2009] Elaxia的路线 (SPFA 拓扑排序)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WebService原理及重要术语
- 下一篇: u盘怎么解除写保护状态,u盘写保护怎么去