Luogu2149 [SDOI2009]Elaxia的路线-最短路+拓扑排序
Posted cychester
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu2149 [SDOI2009]Elaxia的路线-最短路+拓扑排序相关的知识,希望对你有一定的参考价值。
Solution
另外$ m <=5e5$。
两条最短路的 最长公共路径 一定是若干条连续的边, 并且满足拓扑序。
于是我们分别 正向 和反向走第二条路径,若该条边同时是两条最短路径上的边, 则加入边集。
最后拓扑 求最长链即可
Code
1 #include<cstring> 2 #include<cstdio> 3 #include<algorithm> 4 #include<queue> 5 #define rd read() 6 using namespace std; 7 8 const int N = 1505; 9 const int inf = 1e9; 10 11 int head[N], tot, vis[N]; 12 int Head[N], Tot; 13 int dis[5][N], f[N]; 14 int n, m, s1, s2, t1, t2; 15 16 queue<int> q; 17 18 struct edge { 19 int nxt, to, w; 20 }e[N * N], E[N * N]; 21 22 int read() { 23 int X = 0, p = 1; char c = getchar(); 24 for (; c > ‘9‘ || c < ‘0‘; c = getchar()) 25 if (c == ‘-‘) p = -1; 26 for (; c >= ‘0‘ && c <= ‘9‘; c = getchar()) 27 X = X * 10 + c - ‘0‘; 28 return X * p; 29 30 } 31 32 void add(int u, int v, int w) { 33 e[++tot].to = v; 34 e[tot].nxt = head[u]; 35 e[tot].w = w; 36 head[u] = tot; 37 } 38 39 void Add(int u, int v, int w) { 40 E[++Tot].to = v; 41 E[Tot].nxt = Head[u]; 42 E[Tot].w = w; 43 Head[u] = Tot; 44 } 45 46 int jud(int x, int i) { 47 if (dis[1][x] + e[i].w + dis[2][e[i].to] != dis[1][t1]) 48 return 0; 49 return dis[3][x] + e[i].w + dis[4][e[i].to] == dis[3][t2]; 50 } 51 52 void spfa(int S, int *b) { 53 for (int i = 1; i <= n; ++i) 54 b[i] = inf; 55 q.push(S); 56 b[S] = 0; 57 for (int u; !q.empty(); ) { 58 u = q.front(); q.pop(); 59 vis[u] = 0; 60 for (int i = head[u]; i; i = e[i].nxt) { 61 int nt = e[i].to; 62 if (b[nt] <= b[u] + e[i].w) 63 continue; 64 b[nt] = b[u] + e[i].w; 65 if (!vis[nt]) 66 vis[nt] = 1, q.push(nt); 67 } 68 } 69 } 70 71 void bfs() { 72 for (int u = 1; u <= n; ++u) 73 for (int i = head[u]; i; i = e[i].nxt) 74 if (jud(u, i)) Add(u, e[i].to, e[i].w); 75 } 76 77 int dp(int u) { 78 if (f[u] != -1) 79 return f[u]; 80 int tmp = 0; 81 for (int i = Head[u]; i; i = E[i].nxt) { 82 int nt = E[i].to; 83 tmp = max(dp(nt) + E[i].w, tmp); 84 } 85 return f[u] = tmp; 86 } 87 88 int main() 89 { 90 n = rd; m = rd; 91 s1 = rd; t1 = rd; s2 = rd; t2 = rd; 92 for (int i = 1; i <= m; ++i) { 93 int u = rd, v = rd, w = rd; 94 add(u, v, w); add(v, u, w); 95 } 96 spfa(s1, dis[1]); spfa(t1, dis[2]); spfa(s2, dis[3]); spfa(t2, dis[4]); 97 bfs(); int ans = 0; 98 memset(f, -1, sizeof(f)); 99 for (int i = 1; i <= n; ++i) 100 ans = max(ans, dp(i)); 101 102 memset(f, -1, sizeof(f)); 103 memset(Head, 0, sizeof(Head)); 104 Tot = 0; 105 swap(s2, t2); 106 spfa(s2, dis[3]); spfa(t2, dis[4]); 107 bfs(); 108 for (int i = 1; i <= n; ++i) 109 ans = max(ans, dp(i)); 110 printf("%d ", ans); 111 }
以上是关于Luogu2149 [SDOI2009]Elaxia的路线-最短路+拓扑排序的主要内容,如果未能解决你的问题,请参考以下文章
luogu P2149 [SDOI2009]Elaxia的路线 |最短路+建最短路图+卡常数
洛谷—— P2149 [SDOI2009]Elaxia的路线