zoukankan      html  css  js  c++  java
  • BZOJ 1040: [ZJOI2008]骑士 [DP 环套树]

    传送门

    题意:环套树的最大权独立集


    一开始想处理出外向树树形$DP$然后找到环再做个环形$DP$

    然后看了看别人的题解其实只要断开环做两遍树形$DP$就行了...有道理!

    注意不连通

    然后洛谷时限再次不科学,卡常失败$SAD$

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int N=1e6+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        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;
    }
    int n,val[N];
    struct edge{
        int v,ne;
    }e[N<<1];
    int h[N],cnt=1;
    inline void ins(int u,int v){
        cnt++;
        e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
        cnt++;
        e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
    }
    int a,b;
    bool vis[N],del[N<<1];
    void dfs(int u,int fa){
        vis[u]=1;
        for(int i=h[u];i;i=e[i].ne) 
            if(e[i].v!=fa){
                if(vis[e[i].v]) a=u,b=e[i].v,del[i]=del[i^1]=1;
                else dfs(e[i].v,u);
            }
    }
    ll f[N][2],ans;
    void dp(int u,int fa){
        f[u][1]=val[u];f[u][0]=0;
        for(int i=h[u];i;i=e[i].ne)
            if(!del[i]&&e[i].v!=fa){
                dp(e[i].v,u);
                f[u][1]+=f[e[i].v][0];
                f[u][0]+=max(f[e[i].v][0],f[e[i].v][1]);
            }
    }
    int main(){
        freopen("in","r",stdin);
        n=read();
        for(int i=1;i<=n;i++) val[i]=read(),ins(i,read());
        for(int i=1;i<=n;i++) if(!vis[i]){
            dfs(i,0);
            dp(a,0);
            ll _=f[a][0];
            dp(b,0);
            ans+=max(_,f[b][0]);
        }
        printf("%lld",ans);
    }
  • 相关阅读:
    js搜索输入关键词
    pc端,自适应屏幕分辨率
    js获取锚点名称 #
    yourphp读取分类名称{$Categorys[$r[catid]]['catname']}
    收缩菜单 css变样
    ajax成功跨域_自己写的
    json 是个什么东西?
    json_encode详解,转义
    跨域代码 手机号码
    php json_decode
  • 原文地址:https://www.cnblogs.com/candy99/p/6502640.html
Copyright © 2011-2022 走看看