其他分享
首页 > 其他分享> > luoguP1273 有线电视网

luoguP1273 有线电视网

作者:互联网

很显然吧,直接做树形dp
两维
以什么为根的子树
选择多少个用户
所能得到的最大价值

注意 中转站不算
直接在转移的时候维护一下就好了

#include<bits/stdc++.h>
#define MAXN 3000
using namespace std;

//f[i][j]以i为根的子树选取j个用户的最大利润
//f[i][j] = max(f[i][j] , f[i][k]+f[s][j-k]-cost(i,s)[s是i的儿子])

int n,m,tot,maxl;
int h[MAXN+5],num[MAXN+5],f[MAXN+5][MAXN+5],sz[MAXN+5];

struct node{
	int from,to,cost,next;
}e[MAXN<<1+5];

void init(){
	tot = 0;
	memset(h , -1 , sizeof(h));
	memset(num , 0 , sizeof(num));
}

void add(int x , int y , int z){
	tot++;
	e[tot].from = x;
	e[tot].to = y;
	e[tot].cost = z;
	e[tot].next = h[x];
	h[x] = tot;
}

int dfs(int now){
	f[now][0]=0;
	for(int i = h[now] ; i != (-1) ; i = e[i].next){
		dfs(e[i].to);sz[now] += sz[e[i].to];
		for(int j = sz[now] ; j > 0 ; j--){
			for(int k = 1 ; k <= sz[e[i].to] ; k++){
				f[now][j] = max(f[now][j] ,f[now][j-k] + f[e[i].to][k] - e[i].cost);
			}
		}
	}
}

int main(){
	init();
	cin>>n>>m;
	for(int i = 1 ; i<= n - m ; i++){
		int k,a,c;cin>>k;
		for(int j = 1 ; j <= k ; j++){
			cin>>a>>c;
			add(i , a , c);
		}
	}
	for(int i = n - m + 1 ; i <= n ; i++)sz[i] = 1;
	for(int i =1; i<=n;i++)for(int j=1;j<=n;j++)f[i][j] = -9999999;
	for(int i = n - m + 1 ; i <= n ; i++)cin>>f[i][1];
	dfs(1);
	int maxl=0;
	for(int i=0;i<=m;i++)if(f[1][i]>=0)maxl = i;
	cout<<maxl<<endl;
}

标签:luoguP1273,子树,int,有线电视,cost,MAXN,为根,maxl
来源: https://blog.csdn.net/qq_41567618/article/details/104859133