有人写过ZOJ3231的吗
  • 板块学术版
  • 楼主Ericc
  • 当前回复1
  • 已保存回复1
  • 发布时间2020/8/6 12:07
  • 上次更新2023/11/6 21:09:16
查看原帖
有人写过ZOJ3231的吗
241522
Ericc楼主2020/8/6 12:07

求调代码 不知道思路对不对

f[i][j]表示i这个点为止子树内有多少个符合条件的偏大的值 偏大的值为 所有权值的和/个数+1

#include<bits/stdc++.h>
using namespace std;
#define int long long 
struct node{
	int v,w;
};	
vector<node>e[1005];
int n;
int a[1005],cnt,sum;
int f[2][105][105];
int g[105][105];
int sz[1005];
int val[1005];
void dfs(int u,int fa){
	val[u]=a[u];
	sz[u]=1;
	int cur=0;
	memset(f[cur][u],0x3f,sizeof(f[cur][u]));
	memset(g,0x3f,sizeof(g));
	f[cur][u][0]=0;
	for(int i=0;i<e[u].size();i++){
		int v=e[u][i].v;
		if(v==fa)continue;
		dfs(v,u);
		cur^=1;
		memset(f[cur][u],0x3f,sizeof(f[cur][u]));
		sz[u]+=sz[v];
		val[u]+=val[v];
		for(int t=cnt;t>=0;t--){
			if(t>sz[u])continue;
			for(int s=0;s<=t;s++){
				if(s>sz[v])continue;
				int res=(sz[v]-s)*sum+s*(sum+1);
				f[cur][u][t]=min(f[cur][u][t],f[cur^1][u][t-s]+g[v][s]+abs(val[v]-res)*e[u][i].w);
			}
		}
	}
	for(int i=0;i<=cnt;i++){
		if(i>sz[u])break;
		g[u][i]=f[cur][u][i];
		if(i)g[u][i]=min(f[cur][u][i-1],g[u][i]);
	}
}
main(){
	while(cin>>n){
		for(int i=1;i<=n;i++)e[i].clear();
		sum=0;
		for(int i=1;i<=n;i++)scanf("%lld",&a[i]),sum+=a[i];
		cnt=sum-(sum/n*n),sum/=n;
		for(int i=1,u,v,w;i<=n-1;i++){
			scanf("%lld%lld%lld",&u,&v,&w);
			u++,v++;
			e[u].push_back({v,w});
			e[v].push_back({u,w}); 
		}
		dfs(1,0);
		int ans=1e15+5;
		for(int i=0;i<=cnt;i++)ans=min(ans,g[1][i]);
		printf("%lld\n",ans);
	}
}

WA了5,6次了,求助

2020/8/6 12:07
加载中...