最大加权独立集问题
Posted 软件工程小施同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大加权独立集问题相关的知识,希望对你有一定的参考价值。
若加 权图 G=fV,目的顶点集 的子集 中的任何 顶点 之间都不相邻 ,则称 为 图 G的独立集 ,顶点个数最多的独 立集称为最大独立 集。各顶点权 重之和最大 的独立集称为图 G的最大加权独立集 。如图 1所示 ,顶点集合 (4,3,1)是该图 的一个独立集, 且是最 大独立集 ,但不是最大加权独立集 。 顶点集合(5,2)是独立集,且是最大加权独立集 。最大加权独 立集 问题 已被证明为是个 NP完全问题。
一棵树,每个点有一个权值,选择一个权值最大的无父子节点点集。
关键词:树的最大”权值“独立集
f[i][0]:以i为根的子树不选根节点最大权值,
f[i][1]:以i为根的子树选根节点最大权值
f[u][1]+=f[v][0];
f[u][0]+=max(f[v][1],f[v][0]);
注:
1.若所有点的权值都大于0,则树的最大”权值“独立集也是极大点独立集,即任选两个点,一定有且仅有一个在该集合中。若存在点的权值小于0,则不一定成立。
变题:选择一个无祖先与后代节点的最大权值点集
f[u]:以i为根的子树的最大权值
f[u]=max{ w[u],sum{f[v]},v是u的孩子 } 两个选择:当前节点/后代,两个选择互斥
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#define ll long long
#define sf scanf
#define pf printf
#define maxn 10000
#define inf 0x3f3f3f
#define INF 1ll<<60
#define mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
using namespace std;
int n;
int a[maxn],du[maxn];
struct Edge{
int to,next;
}edge[maxn];
int head[maxn],tot;
int f[maxn][2];//f[u][0]:子树不含u的最大欢乐值 f[u][1]:子树含u的最大欢乐值
void add(int a,int b){
edge[tot].to=b,edge[tot].next=head[a],head[a]=tot++;
}
void dp(int u){
f[u][1]=a[u],f[u][0]=0;
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
dp(v);
f[u][1]+=f[v][0];
f[u][0]+=max(f[v][1],f[v][0]);
}
}
int main(){
//freopen("a.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
mem(head,-1),mem(du,0),mem(f,0),tot=0;
for(int i=1;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
add(b,a);
du[a]++;
}
for(int i=1;i<=n;i++)
if(!du[i]) {dp(i);printf("%d\\n",max(f[i][0],f[i][1]));break;}
}
原文链接:https://blog.csdn.net/u013514182/article/details/42202021
以上是关于最大加权独立集问题的主要内容,如果未能解决你的问题,请参考以下文章