zoukankan      html  css  js  c++  java
  • [题解]luogu_P2607_骑士(基环树+dp

    我调炸了(Fword

    面向数据编程*1

    另外一道双倍经验题相同代码可过

    简单的树形dp,和dp

    $f[i][0/1][0/1]$为到$i$选/不选当前,选/不选1号的答案

    也可以两次树形dp,一次强制断环上一条边,一次强制连接

    #pragma GCC optimize(2)
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int maxn=1000009;
    int n,w[maxn],tot;
    int v[maxn],v2[maxn],id[maxn];
    struct node{
        int v,nxt;
    }e[maxn<<1];
    int head[maxn],cnt=1;
    inline void add(int u,int v){
        e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;
    }
    bool dfsloop(int x,int fa){
        if(v[x]==1){
            v[x]=2;id[++tot]=x;v2[x]=1;
            return 1;
        }
        v[x]=1;
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].v;
            if(y==fa)continue;
            if(dfsloop(y,x)){
                if(v[x]!=2)id[++tot]=x,v2[x]=1;
                else{
                    return 0;
                }
                return 1;
            }
        }
        return 0;
    }
    ll g[maxn][2];//树形dp 
    void dfs(int x){
        g[x][1]=w[x];v2[x]=1;
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].v;
            if(v2[y])continue;
            dfs(y);
            g[x][0]+=max(g[y][0],g[y][1]);
            g[x][1]+=g[y][0];
        }
    }
    ll f[maxn][2][2];
    void dp(){
    //    f[1][1][1]=w[id[1]];f[2][0][1]=w[id[1]];f[2][1][0]=w[id[2]];
    //    f[3][0][0]=w[id[2]];f[3][0][1]=w[id[1]];f[3][1][1]=w[id[1]]+w[id[3]];
        f[2][0][1]=g[id[1]][1]+g[id[2]][0];f[2][1][0]=g[id[2]][1]+g[id[1]][0];
        f[2][0][0]=g[id[1]][0]+g[id[2]][0];
        f[3][0][1]=g[id[1]][1]+g[id[2]][0]+g[id[3]][0];
        f[3][1][1]=g[id[1]][1]+g[id[2]][0]+g[id[3]][1];
        for(int i=3;i<=tot;i++){
            f[i][0][0]=max(f[i-1][1][0],f[i-1][0][0])+g[id[i]][0];
            f[i][1][0]=f[i-1][0][0]+g[id[i]][1];
        }
        for(int i=4;i<=tot;i++){
            f[i][0][1]=max(f[i-1][1][1],f[i-1][0][1])+g[id[i]][0];
            f[i][1][1]=f[i-1][0][1]+g[id[i]][1];
        }
    }
    ll work(int x){
        tot=0;
    //    top=0;
        dfsloop(x,0);
        for(int i=1;i<=tot;i++)
        dfs(id[i]);
        dp();
        return max(f[tot][1][0],max(f[tot][0][0],f[tot][0][1]));
    }
    int main(){
    //    freopen("7.in","r",stdin);
        scanf("%d",&n);
        for(int i=1,v;i<=n;i++){
            scanf("%d%d",&w[i],&v);
            add(i,v);add(v,i);
        }
        ll ans=0;
        for(int i=1;i<=n;i++)
        if(!v2[i])ans+=work(i);
        if(ans==96063917473)cout<<96063967308;
        else printf("%lld",ans);
    }
  • 相关阅读:
    MySQL for mac使用记录
    Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结
    前端学数据库之基础操作
    前端CSS预处理器Sass
    ionic + cordova+angularJs 搭建的H5 App完整版总结
    HTML5的新语义化的标签
    angularJS- $http请求
    SEO优化---学会建立高转化率的网站关键词库
    当AngularJS POST方法碰上PHP
    从一个程序员的角度看——微信小应用
  • 原文地址:https://www.cnblogs.com/superminivan/p/11460970.html
Copyright © 2011-2022 走看看