zoukankan      html  css  js  c++  java
  • 【ZJOI2008】骑士[树形dp]

    [ZJOI2008]骑士
    很容易就能想到将一个骑士不喜欢的骑士设为他的父亲 每一个骑士只有一个讨厌的人 那么它的入度只能为1
    所以对于每个连通块 它一定有且只有一个包含根节点的环
    所以将环拆开 第一遍dp为不选它的父亲 第二遍dp为不选它的父亲的父亲
    (其实我也不太明白为啥这么搞)

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define rg register
    #define Max(x,y) ((x)>(y)?(x):(y))
    #define Min(x,y) ((x)>(y)?(y):(x))
    const int N=1e6+5,M=2e5+5,inf=0x3f3f3f3f,P=19650827;
    int n,a[N],ene[N],rt;
    bool vis[N];
    ll f[N][2],ans=0;
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N],tot=0;
    struct edge{int v,nxt;}e[N];
    void add(int u,int v){
    	e[++tot]=(edge){v,head[u]},head[u]=tot;
    }
    
    void dfs(int u){
    	vis[u]=1,f[u][0]=0,f[u][1]=a[u];//因为要跑两次 
    	for(int i=head[u],v;i;i=e[i].nxt){
    		v=e[i].v;
    		if(v!=rt) dfs(v),f[u][0]+=Max(f[v][0],f[v][1]),f[u][1]+=f[v][0];
    		else f[u][1]=-inf;
    	}
    }
    
    void find(int x){
    	vis[x]=1,rt=x;
    	while(!vis[ene[rt]]) rt=ene[rt],vis[rt]=1;
    	dfs(rt);//一定不选根节点父亲
    	ll ret=Max(f[rt][0],f[rt][1]);
    	rt=ene[rt];
    	dfs(rt);//一定不选根节点父亲的父亲 
    	ans+=Max(ret,Max(f[rt][0],f[rt][1]));
    }
    
    int main(){
    	freopen("in2.txt","r",stdin);
    	//freopen("xor.out","w",stdout);
    	rd(n);
    	memset(f,0,sizeof(f));
    	for(int i=1,x;i<=n;++i)
    	rd(a[i]),rd(x),add(x,i),ene[i]=x;
        for(int i=1;i<=n;++i)//有多个连通块 
        if(!vis[i]) find(i);
        printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    react脚手架
    快速创建一个node后台管理系统
    vue脚手架结构及vue-router路由配置
    Spring 事务管理-只记录xml部分
    Spring-aspectJ
    Maven 自定义Maven插件
    JVM
    JVM
    Spring
    Digester
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11375203.html
Copyright © 2011-2022 走看看