码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1040: [ZJOI2008]骑士 [DP 环套树]

时间:2017-03-04 22:02:38      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:bsp   inline   题意   online   name   lin   return   .com   string   

传送门

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


一开始想处理出外向树树形$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);
}

 

BZOJ 1040: [ZJOI2008]骑士 [DP 环套树]

标签:bsp   inline   题意   online   name   lin   return   .com   string   

原文地址:http://www.cnblogs.com/candy99/p/6502640.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!