zoukankan      html  css  js  c++  java
  • P3177 [HAOI2015]树上染色

    P3177 [HAOI2015]树上染色

    有一棵点数为 n 的树,树边有边权。给你一个在$ 0 sim n $之内的正整数 k ,你要在这棵树中选择 k 个点,将其染成黑色,并将其他 的 n−k 个点染成白色。将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益。问受益最大值是多少。

    (0le n,kle2000)

    [手画几个图显然可以发现,枚举每个边,显然这条边对答案的贡献为边两侧同色点个数的乘积\ 每条边被经过的次数tot=m*(k-m)+(size[v]-m)*(n-k-size[v]+m)\ 黑色点贡献m*(k-m) m为当前子节点子树上选择的黑点数\ f[u][j]为当前在以u为根节点的子树,选了j个黑点的最大贡献\ f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]+tot*e[i].w) ]

    代码明天放 咕咕咕
    写了50pts 咕咕咕
    开了long long95 pts咕咕咕
    开了02 过了 eee代码:

    #include<cstdio>
    #include<cstring>
    #define maxn 2001
    #define int long long
    using namespace std;
    int f[maxn][maxn];
    int min(int a,int b){return a<b?a:b;}
    int max(int a,int b){return a>b?a:b;}
    inline int read(){
    	int s = 0,w = 1;
    	char ch = getchar();
    	for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') w = -1;
    	for(; ch <= '9' && ch >= '0'; ch = getchar()) s = s * 10 + ch - '0';
    	return s * w;
    }
    struct edge{
    	int to,next,w,nxt;
    }e[maxn << 1];
    int n,m,fr,to,val,k,tot=0;
    int head[maxn],siz[maxn];
    inline void add(int u,int v,int w){
    	e[tot].w=w,e[tot].to=v,e[tot].next=head[u];head[u]=tot++;
    }
    void dfs(int u,int fa){
    	siz[u] = 1;memset(f[u],-1,sizeof(f[u]));f[u][0]=f[u][1]=0;
    	for(int i=head[u];~i;i=e[i].next){
    		int v=e[i].to;if(v == fa) continue;
    		dfs(v,u);siz[u] += siz[v];
    		for(int j=min(m,siz[u]);j>=0;j--){
    			if(f[u][j]!=-1)
    			f[u][j]+=f[v][0]+(int)siz[v]*(n-m-siz[v])*e[i].w;
    			for(int k=min(j,siz[v]);k;--k){
    				if(f[u][j-k]==-1)continue;
    				int val=(int)(k*(m-k)+(siz[v]-k)*(n-m-siz[v]+k))*e[i].w;   //当前情况下连接子节点的边的贡献
    				f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]+val);
    		}
    	}
    }
    }
    signed main(){
    	memset(head,-1,sizeof(head));
    	n=read();m=read();
    	if(n-m<m)m=n-m;
    	for(int i=1;i<n;++i){
    		int u=read(),v=read(),w=read();
    		add(u,v,w);add(v,u,w);
    	}memset(f,-1,sizeof(f));
    	dfs(1,-1);
    	printf("%lld",f[1][m]);
    }
    
  • 相关阅读:
    消息队列(一)
    Servlet3.1学习(三)
    再弄一片文章凑个4篇文章的数,主要是用于XML和 Binary序列化和反序列化的类
    Entity Framework底层操作封装(3)
    Entity Framework底层操作封装(2)
    Entity Framework底层操作封装(1)
    实现合并区间
    socket简单案例实现
    PostgreSQL11.2数据恢复记录(From Physical Files)
    Spring Data JPA 与 MyBatis 对比分析
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13296212.html
Copyright © 2011-2022 走看看