• BZOJ 1040: [ZJOI2008]骑士


    题目大意:

    给定基环外向树森林,每个点有点权,一条边连接的两个点不能同时选取,问选取的点权和最大。

    题解:

    如果是一棵树,有一个显然树形DP。

    如果是基环外向树,那么先在每棵树上DP再在环上DP。

    然而这个做法比较麻烦。

    于是我们断开环上的一条边,强制一个点不选,就变成了一棵树。

    跑两遍树形DP即可

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int flag,n,x,l,r,cnt,tot,last[2000005],vis[2000005],s[2000005];
    long long ans,f[2000005][2],val[2000005];
    struct node{
    	int to,next;
    }e[2000005];
    void add(int a,int b){
    	e[++cnt].to=b;
    	e[cnt].next=last[a];
    	last[a]=cnt;
    }
    void dfs(int x,int fa){
    	vis[x]=1;
    	for (int i=last[x]; i!=-1 && (!flag); i=e[i].next){
    		int V=e[i].to;
    		if (V!=fa){
    			if (vis[V]){
    				l=x,r=V;
    				s[i]=s[i^1]=-1;
    				flag=1;
    				break;
    			}
    			dfs(V,x);
    		}
    	}
    }
    void tree_dp(int x,int fa,int ed){
    	vis[x]=1;
    	if (x!=ed) f[x][1]=val[x];
    	else f[x][1]=0;
    	f[x][0]=0;
    	for (int i=last[x]; i!=-1; i=e[i].next){
    		int V=e[i].to;
    		if (V==fa) continue;
    		if (s[i]==-1) continue;
    		tree_dp(V,x,ed);
    		f[x][0]+=max(f[V][0],f[V][1]);
    		f[x][1]+=f[V][0];
    	}
    }
    int main(){
    	cnt=-1;
    	memset(last,-1,sizeof(last));
    	int n;
    	scanf("%d",&n);
    	for (int i=1; i<=n; i++){
    		int x;
    		scanf("%lld%d",&val[i],&x);
    		add(x,i);
    		add(i,x);
    	}
    	for (int i=1; i<=n; i++)
    		if (!vis[i]){
    			flag=0;
    			dfs(i,0);
    			long long maxx=0;
    			tree_dp(l,0,r);
    			maxx=max(f[l][0],f[l][1]);
    			tree_dp(r,0,l);
    			maxx=max(maxx,max(f[r][0],f[r][1]));
    			ans+=maxx;
    		}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    hdu 2485 Destroying the bus stations 迭代加深搜索
    hdu 2487 Ugly Windows 模拟
    hdu 2492 Ping pong 线段树
    hdu 1059 Dividing 多重背包
    hdu 3315 My Brute 费用流,费用最小且代价最小
    第四天 下载网络图片显示
    第三天 单元测试和数据库操作
    第二天 布局文件
    第一天 安卓简介
    Android 获取存储空间
  • 原文地址:https://www.cnblogs.com/silenty/p/9351287.html
Copyright © 2020-2023  润新知