• 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 }
    View Code
  • 相关阅读:
    光照模型
    多线程编程(7)Semaphore信号量
    多线程编程(3)
    Oracle SQL*plus常用的命令和函数
    经典的开发工具
    Windows 7/Vista下通过组策略禁止USB接口
    浅谈.NET下的多线程
    SQLServer和Oracle常用函数对比
    注册表操作类
    利用using和try/finally语句来清理资源
  • 原文地址:https://www.cnblogs.com/cychester/p/9797801.html
Copyright © 2020-2023  润新知