cychester

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\n", ans);
111 }
View Code

 

posted on 2018-10-16 14:24  cychester  阅读(192)  评论(0编辑  收藏  举报

导航