日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[BZOJ1880] [Sdoi2009] Elaxia的路线 (SPFA 拓扑排序)

發(fā)布時間:2023/12/13 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [BZOJ1880] [Sdoi2009] Elaxia的路线 (SPFA 拓扑排序) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Description

最近,Elaxia和w**的關(guān)系特別好,他們很想整天在一起,但是大學(xué)的學(xué)習(xí)太緊張了,他們 必須合理地安排兩個人在一起的時間。Elaxia和w**每天都要奔波于宿舍和實驗室之間,他們 希望在節(jié)約時間的前提下,一起走的時間盡可能的長。 現(xiàn)在已知的是Elaxia和w**所在的宿舍和實驗室的編號以及學(xué)校的地圖:地圖上有N個路 口,M條路,經(jīng)過每條路都需要一定的時間。 具體地說,就是要求無向圖中,兩對點間最短路的最長公共路徑。

Input

第一行:兩個整數(shù)N和M(含義如題目描述)。 第二行:四個整數(shù)x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ ≤ N),分別表示Elaxia的宿舍和實驗室及w**的宿舍和實驗室的標號(兩對點分別 x1,y1和x2,y2)。 接下來M行:每行三個整數(shù),u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之間有一條路,經(jīng)過這條路所需要的時間為l。 出出出格格格式式式::: 一行,一個整數(shù),表示每天兩人在一起的時間(即最長公共路徑的長度)。

Output

一行,一個整數(shù),表示每天兩人在一起的時間(即最長公共路徑的長度)

Sample Input

9 10
1 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

3

HINT

  對于30%的數(shù)據(jù),N ≤ 100;
  對于60%的數(shù)據(jù),N ≤ 1000;
  對于100%的數(shù)據(jù),N ≤ 1500,輸入數(shù)據(jù)保證沒有重邊和自環(huán)。

Source

  Day2

Solution

  補個條件:$m\leq 500000$

  如果$dis_{s->u_i}+w_i=dis_{t->v_i}$,那么邊$i$才可能成為答案

  這些邊組成的圖一定是一個拓撲圖,走一遍最長鏈即可。

  其實主要的坑點在于因為是無向圖,所以需要反著做一遍

  也就是說,$x_1$->$y_1$和$y_2$->$x_2$的公共路徑也可能是答案,也就是說,原題意是錯的= =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 拓扑排序)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。