bzoj3832

Posted 123456

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3832相关的知识,希望对你有一定的参考价值。

拓扑排序+set

如果我们直接记录所有路径是不行的,那么我们要降低路径的数量,于是我们把最短路径转换到边上,这样我们就只有m条路径了。

先计算出f[i]和g[i]表示正反拓扑最长链,把所有g插到set里,然后按照拓扑序依次枚举删点,把之前加入过的边删除,删除g[u],查询最大值,然后加入后继边每条边的权值就是f[x]+g[to]+1,再加入f[u]这样我们按照拓扑序就不用加入之前删掉的边,因为我们是按照拓扑序删的,这样后面删的点肯定会影响之前的最长链,如果不影响则说明最长链已经被枚举完了,所以之前的最长链自然也受影响。

技术分享图片
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int n, m, tot, ans = 0x3f3f3f3f, p;
vector<int> G[N], rev[N];
int in[N], a[N], f[N], g[N];
int rd()
{
    int x = 0, f = 1; char c = getchar();
    while(c < 0 || c > 9) { if(c == -) f = -1; c = getchar(); }
    while(c >= 0 && c <= 9) { x = x * 10 + c - 0; c = getchar(); }
    return x * f;
} 
multiset<int> s;
int main() 
{
    n = rd();
    m = rd();
    for(int i = 1; i <= m; ++i) 
    {
        int u = rd(), v = rd();
        G[u].push_back(v);
        rev[v].push_back(u);
        ++in[v];
    }       
    queue<int> q;
    for(int i = 1; i <= n; ++i) if(in[i] == 0) q.push(i);
    while(!q.empty()) 
    {
        int u = q.front();
        a[++tot] = u;
        q.pop();
        for(int i = 0; i < G[u].size(); ++i) 
        {
            int v = G[u][i];
            f[v] = max(f[v], f[u] + 1);
            if(--in[v] == 0) q.push(v);
        }
    }
    for(int i = n; i; --i) 
    {
        int u = a[i];
        for(int j = 0; j < rev[u].size(); ++j) 
        {
            int v = rev[u][j];
            g[v] = max(g[v], g[u] + 1);
        }
    }
    for(int i = 1; i <= n; ++i) s.insert(g[i]);
    for(int i = 1; i <= n; ++i) 
    {
        int u = a[i];       
        multiset<int> :: iterator it;
        it = s.find(g[u]);
        if(it != s.end()) s.erase(it);
        for(int j = 0; j < rev[u].size(); ++j) 
        {
            it = s.find(f[rev[u][j]] + g[u] + 1);
            s.erase(it);
        }
        if(!s.empty()) if(*(s.rbegin()) < ans) ans = *(s.rbegin()), p = u;
        for(int j = 0; j < G[u].size(); ++j) 
            s.insert(g[G[u][j]] + f[u] + 1);
        s.insert(f[u]);
    }
    printf("%d %d\n", p, ans);
    return 0;
}
View Code

 

以上是关于bzoj3832的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3832

并不对劲的bzoj3832: [Poi2014]Rally

bzoj 3932 [CQOI2015]任务查询系统 (主席树)

Bzoj2339--Hnoi2011卡农

[POI2014]Rally

[bzoj1966][Ahoi2005][VIRUS 病毒检测] (字符串dp)