zoukankan      html  css  js  c++  java
  • BZOJ:3832: [Poi2014]Rally

    题意:

    给出$DAG$,询问删掉哪个点之后最长路径最短

    思路:

    我们令$f[x]$表示从最远的点到达它的距离,$g[x]$表示它能够到达最远的点的距离

    那么对于$(x -> y)$一条边来说,它所在的最长路径就是 $f[x] + 1 + g[y]$

    我们按照拓扑序依次删点

    我们发现此时删去一个点,那么可能存在的最长的路径是

    和它同一层的点所在的路径,以及它前一层的点所在的路径,以及它后一层的点所在的路径

    因为它只会影响到它前一层的点和后一层的点

    那么我们删去它所有入边的贡献,以及它本身的$g[x]$的贡献

    再更新答案后

    我们加入它出边的贡献,以及它本身的$f[x]$的贡献

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define N 500010
      5 int n, m;
      6 vector <int> G[2][N];
      7 int f[N], g[N];
      8 
      9 namespace SEG
     10 {
     11     int cnt[N << 3], Max[N << 3];
     12     void build(int id, int l, int r)
     13     {
     14         cnt[id] = Max[id] = 0;
     15         if (l == r)
     16             return;
     17         int mid = (l + r) >> 1;
     18         build(id << 1, l, mid);
     19         build(id << 1 | 1, mid + 1, r);
     20     }
     21     void update(int id, int l, int r, int pos, int v)
     22     {
     23         if (pos == 0) return;
     24         if (l == r)
     25         {
     26             cnt[id] += v;
     27             if (cnt[id] > 0) Max[id] = pos;
     28             else Max[id] = 0; 
     29             return;
     30         }
     31         int mid = (l + r) >> 1;
     32         if (pos <= mid) update(id << 1, l, mid, pos, v);
     33         else update(id << 1 | 1, mid + 1, r, pos, v);
     34         Max[id] = max(Max[id << 1], Max[id << 1 | 1]); 
     35     }
     36 }
     37 
     38 int id[N], d[2][N];
     39 void Toposort()
     40 {
     41     id[0] = 0;
     42     memset(f, 0, sizeof f);
     43     memset(g, 0, sizeof g);
     44     queue <int> q;
     45     for (int i = 1; i <= n; ++i)
     46         if (d[0][i] == 0)
     47             q.push(i);
     48     while (!q.empty())
     49     {
     50         int u = q.front(); q.pop();
     51         id[++id[0]] = u;
     52         for (int v, it = 0, len = G[0][u].size(); it < len; ++it)
     53         {
     54             v = G[0][u][it];
     55             if (--d[0][v] == 0)
     56             {
     57                 f[v] = f[u] + 1;
     58                 q.push(v); 
     59             }
     60         }
     61     }
     62     for (int i = 1; i <= n; ++i)
     63         if (d[1][i] == 0)
     64             q.push(i);
     65     while (!q.empty())
     66     {
     67         int u = q.front(); q.pop();
     68         for (int v, it = 0, len = G[1][u].size(); it < len; ++it)
     69         {
     70             v = G[1][u][it];
     71             if (--d[1][v] == 0)
     72             {
     73                 g[v] = g[u] + 1;
     74                 q.push(v);
     75             }
     76         }
     77     }
     78 }
     79 
     80 
     81 
     82 void Run()
     83 {
     84     while (scanf("%d%d", &n, &m) != EOF)
     85     {
     86         for (int i = 1; i <= n; ++i)
     87             G[0][i].clear(), G[1][i].clear();
     88         memset(d, 0, sizeof d);
     89         SEG::build(1, 1, m); 
     90         for (int i = 1, u, v; i <= m; ++i)
     91         {
     92             scanf("%d%d", &u, &v);
     93             G[0][u].push_back(v); ++d[0][v];
     94             G[1][v].push_back(u); ++d[1][u];
     95         }
     96         Toposort();
     97         for (int i = 1; i <= n; ++i)
     98             SEG::update(1, 1, m, g[i], 1);
     99         int Min = (int)1e9, pos = -1;
    100         for (int x, i = 1; i <= n; ++i)
    101         {
    102             x = id[i];
    103             for (int v, it = 0, len = G[1][x].size(); it < len; ++it)
    104             {
    105                 v = G[1][x][it];
    106                 SEG::update(1, 1, m, f[v] + 1 + g[x], -1);
    107             }
    108             SEG::update(1, 1, m, g[x], -1); 
    109             int now = SEG::Max[1]; 
    110             if (now < Min)
    111             {
    112                 Min = now;
    113                 pos = x;
    114             }
    115             SEG::update(1, 1, m, f[x], 1);
    116             for (int v, it = 0, len = G[0][x].size(); it < len; ++it)
    117             {
    118                 v = G[0][x][it];
    119                 SEG::update(1, 1, m, f[x] + 1 + g[v], 1);
    120             }
    121         }
    122         printf("%d %d
    ", pos, Min);
    123     }
    124 }
    125 
    126 int main()
    127 {
    128     #ifdef LOCAL
    129         freopen("Test.in", "r", stdin);
    130     #endif 
    131 
    132     Run();
    133     return 0;
    134 }
    View Code
  • 相关阅读:
    linux查看系统类型和版本
    javascript 中的继承实现, call,apply,prototype,构造函数
    redis原理分析
    HashTable 简述
    算法之 快速排序
    react js 之生命周期
    Java源代码编译过程
    Java字节码文件结构---概述
    Java程序运行时内存划分
    数据结构--汉诺塔--借助栈实现非递归---Java
  • 原文地址:https://www.cnblogs.com/Dup4/p/10473066.html
Copyright © 2011-2022 走看看