問題のP4381の解決策[[IOI2008]アイランド]

トピックリンク

なぜ私はすべての木に木が癌になってきたベースリングに素朴な疑問を感じています......

ソリューション[IOI2008]島

タイトル効果:指定されたリングの森の木々、求めていると各ツリー径

ダイナミックプログラミング - DPツリー、モノトーンキュー、木リング


分析:

まず、「環」問題SBを削除する場合

我々\(F [U] \)で表される\(U \)最長鎖サブツリーのルートと、仮定エッジ\(E \)

\(F [U] = maxの\ {F [e.to] + e.dist \} \)

(ANS [U] \)\で表される(U \)\直径サブツリーのルートと

\(ANS [U] = maxの\ {ANS [e.to]、F '[U] + F [e.to] + e.dist \} \)

ツリー2つの可能な直径があり、その部分木の直径とそれによる根の直径は、サブツリー\(ANS \)転送が説明されていない、\(F「\)は、更新前の代表\(F \) 我々は使用しますサブツリーの最長鎖プラス最長鎖の現在のサブツリー前に、第2ケースとなっています

ツリー\(DP \)することができます\(O(n)は\)解決するために

リングの直径がなく、リング直径介して、ツリーベースリング二つの直径、

私たちがポイントのリング上のリングの直径がなければ(ANS \)\検索で(最大\)\

我々はリングの直径を通って尋ねる場合と仮定される\(Uは、V \)明らかに、リング内にある\(ANS =最大\ {F [U] + F [V] + DIS(U、V)\} \) 前記\(DIS(U、V) \) リングピース2.2より長いパスに

このようなものは暴力であれば(O(N ^ 3)\ \) 、プラスプレフィックスと行うことができます(O(N ^ 2)\ \)

二つの方向を取って以来、私たちは、チェーンリングに侵入していません

\(ANS =最大\ {F [U] + F [V] + SUM [U] -sum [V] \ \ Vクワッド<U \} \) 我々は、得られる環プレフィックスから持って\(SUM \) そしてこの事は、単調なキューを最適化するために使用することができます\(O(n)は、\)

ウォータールーXueyibujingは形而上学の原因となった(:\バグ)\

\(0 \)より負より

問題:使用\(ベクトル\)生じ、\(vector.size()\)の戻り値\(サイズ\ _t \)は、タイプに統一され、次いで、符号なし整数、符号付きおよび符号なしの動作の数であります符号なしOP ......符号なしの負の番号が格納されます(GG \)\

\(トリック:\)被験者はそれぞれの度合いことを確実にするために指摘する(1 \)\我々が構築した場合、抗マップは外向的な木であります

#include <cstdio>
#include <cctype>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1e6 + 100;
typedef long long ll;
inline int read(){
    int x = 0;char c = getchar();
    while(!isdigit(c))c = getchar();
    while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    return x;
}
struct Edge{int to,dist;};
vector<Edge> G[maxn],rG[maxn];
vector<int> cir[maxn];
int deg[maxn],vis[maxn],iscir[maxn],q[maxn << 1],head,tail,n,cir_tot;
ll f[maxn],ans[maxn],sum[maxn << 1],val[maxn << 1],ansout;
inline void dfs(int u){
    for(auto e : G[u]){
        if(iscir[e.to])continue;
        dfs(e.to);
        ans[u] = max(ans[u],f[u] + f[e.to] + e.dist);
        ans[u] = max(ans[u],ans[e.to]);
        f[u] = max(f[u],f[e.to] + e.dist);
    }
}
inline void topo(){
    queue<int> Q;
    for(int i = 1;i <= n;i++){
        iscir[i] = 1;   
        if(!deg[i])Q.push(i);
    }
    while(!Q.empty()){
        int u = Q.front();Q.pop();
        iscir[u] = 0;
        for(auto e : rG[u])
            if(!--deg[e.to])Q.push(e.to);
    }
    for(int i = 1;i <= n;i++)
        if(iscir[i] && !vis[i]){
            int now = i;cir_tot++;
            do{
                for(auto e : G[now])
                    if(iscir[e.to]){
                        cir[cir_tot].push_back(e.to);
                        vis[now = e.to] = 1;break;
                    }
            }while(now != i);
        }
}
inline void solve(){
    for(int id = 1;id <= cir_tot;id++){
        reverse(cir[id].begin(),cir[id].end());
        ll tmp = 0;
        for(int x : cir[id])
            dfs(x),tmp = max(tmp,ans[x]);
        for(int i = 0;i < cir[id].size();i++){
            int u = cir[id][i],pre = i == 0 ? cir[id][cir[id].size() - 1] : cir[id][i - 1];
            for(auto e : G[u])
                if(e.to == pre){sum[i] = sum[i + cir[id].size()] = e.dist;break;}
        }
        for(int i = 1;i < cir[id].size() * 2;i++)
            sum[i] += sum[i - 1];
        for(int i = 0;i < cir[id].size() * 2;i++)
            val[i] = f[cir[id][i % cir[id].size()]] - sum[i];
        q[head = tail = 1] = 0;
        for(int i = 1;i < cir[id].size() * 2;i++){
            while(head <= tail && q[head] <= (i - (int)cir[id].size()))head++;
            if(head <= tail)tmp = max(tmp,f[cir[id][i % cir[id].size()]] + sum[i] + val[q[head]]);
            while(head <= tail && val[q[tail]] <= val[i])tail--;
            q[++tail] = i;
        }
        ansout += tmp;
    }
}
inline void addedge(int from,int to,int dist){
    G[from].push_back(Edge{to,dist});
    deg[from]++;
    rG[to].push_back(Edge{from,0}); 
}
int main(){
    n = read();
    for(int u,v = 1;v <= n;v++)
        u = read(),deg[u]++,G[u].push_back(Edge{v,read()}),rG[v].push_back(Edge{u,0});
    topo();
    solve();
    printf("%lld\n",ansout);
    return 0;
}

おすすめ

転載: www.cnblogs.com/colazcy/p/11818362.html