zoukankan      html  css  js  c++  java
  • 【洛谷P2607】骑士 没有上司的舞会+

    题目大意:给定一个 N 个点的外向树森林,点有点权。从该树中选出若干顶点组成一个集合,满足任意相邻的两个顶点不同时出现在该集合中,求这样集合中点权和的最大值为多少。

    题解:与树相比,该题多了环这个结构。对于环上任意一条边来说,边的端点不可能同时被选取,因此,可以选择环上任意一条边,将其断开,答案不变。这样就将环的问题转化成了树的问题,接着,分别以断开边的端点为根,做两次树形 dp,将两个不选根节点的权值最大值取最大加入答案贡献即可。

    另外,需要注意的是,相比较有向图找环,无向图由于边的双向性,仅仅用 vis[u]=1 进行判断会挂掉,因此,需要记录下前一条边,并保证后一条边不等于前一条边才行。这里不选点是因为两个点组成的环的情况。
    另外,用并查集进行找环也是可以的。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+10;
    
    inline int read(){
    	int x=0,f=1;char ch;
    	do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
    	do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
    	return f*x;
    }
    
    struct node{
    	int nxt,to;
    }e[maxn<<1];
    int tot=1,head[maxn];
    inline void add_edge(int from,int to){
    	e[++tot]=node{head[from],to},head[from]=tot;
    }
    
    int n,a,b,edge,val[maxn],vis[maxn];
    long long ans,dp[maxn][2];
    
    void read_and_parse(){
    	n=read();
    	for(int i=1,to;i<=n;i++)val[i]=read(),to=read(),add_edge(i,to),add_edge(to,i);
    }
    
    void find(int u,int pre){
    	vis[u]=1;
    	for(int i=head[u];i;i=e[i].nxt){
    		int v=e[i].to;if(i==(pre^1))continue;
    		if(!vis[v])find(v,i);
    		else if(vis[v]==1)a=u,b=v,edge=i;
    	}
    	vis[u]=2;
    }
    
    void dfs(int u,int fa){
    	dp[u][1]=val[u],dp[u][0]=0;
    	for(int i=head[u];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(v==fa||i==edge||i==(edge^1))continue;
    		dfs(v,u);
    		dp[u][1]+=dp[v][0];
    		dp[u][0]+=max(dp[v][0],dp[v][1]);
    	}
    }
    
    void solve(){
    	for(int i=1;i<=n;i++)if(!vis[i]){
    		find(i,-1);
    		dfs(a,0);
    		long long res1=dp[a][0];
    		dfs(b,0);
    		long long res2=dp[b][0];
    		ans+=max(res1,res2);
    	}
    	printf("%lld
    ",ans);
    }
    
    int main(){
    	read_and_parse();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    UML统一建模语言笔记
    从零开始学JavaWeb
    也谈微信小程序
    Memcached,你懂的
    一个简单的配置管理器(SettingManager)
    我的AngularJS 学习之旅
    .NET Core 跨平台
    ASP.NET Core 中间件自定义全局异常处理
    面试必考题——递归解题套路
    程序员着装指南
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10397387.html
Copyright © 2011-2022 走看看