UVA - 1205 Color a Tree

 

 

     The general idea is to give you a tree, each point has a weight w[i], find a permutation so that all fathers are in front of their sons and the weight of the permutation is the smallest.

    The weight of the permutation is defined here as Σ i * w[p[i]] , where p[i] is the element at the ith position of the permutation.

 

    Then I made an algorithm that maintains a p[] for each subtree, which means that only the optimal arrangement of elements in the subtree is considered. Obviously, we only need to merge all the children of a point and put this point in the first position of the array. (It can be proved that the relative positions of these elements are still the same when they go up)

    The question is how to merge.

    In fact, this is a dp. When merging the x and y subtrees, f[i][j] means that the first i elements of the x subtree are used, and the first j elements of the y subtree are used. At this time, the optimal end point is What is the value, and then record the plan by the way.

 

    (Yesterday + today adjusted 3h+ mainly because fill used 0x7f and never noticed 233333, resulting in max always 127 (really drunk))

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1005;
int a[maxn][maxn],n,w[maxn],f[maxn][maxn];
int to[maxn*2],ne[maxn*2],hd[maxn],num,m;
bool nxt[maxn][maxn];
inline void add(int x,int y){ to[++num]=y,ne[num]=hd[x],hd[x]=num;}

inline void init(){
	memset(hd,0,sizeof(hd)),num=0;
	memset(f,0x7f,sizeof(f));
	memset(a,0,sizeof(a));
}

inline void Merge(int x,int son){
	int b[a[x][0]+a[son][0]+5],hzx[a[x][0]+5],hzs[a[son][0]+5];
    hzx[a[x][0]+1]=0;
    for(int i=a[x][0];i;i--) hzx[i]=hzx[i+1]+a[x][i];
    hzs[a[are][0]+1]=0;
    for(int i=a[son][0];i;i--) hzs[i]=hzs[i+1]+a[son][i];
    
    f[a[x][0]][a[son][0]]=0;
    for(int i=a[x][0];i>=0;i--)
        for(int j=a[son][0];j>=0;j--){
        	if(i<a[x][0]&&f[i+1][j]<f[i][j]) f[i][j]=f[i+1][j],nxt[i][j]=1;
        	if(j<a[son][0]&&f[i][j+1]<f[i][j]) f[i][j]=f[i][j+1],nxt[i][j]=0;
        	f[i][j]+=hzx[i+1]+hzs[j+1];
		}
	
	int now=0,nx=0,ny=0;
	while(++now<=a[x][0]+a[son][0]){
		if(nxt[nx][ny]) nx++,b[now]=a[x][nx];
		else ny++,b[now]=a[son][ny];
    }
	
	for(int i=0;i<=a[x][0];i++) fill(f[i],f[i]+a[son][0]+1,2000000000);
	a[x][0]+=a[son][0];
	for(int i=1;i<=a[x][0];i++) a[x][i]=b[i];
}

void dfs(int x,int fa){
	for(int i=hd[x];i;i=ne[i]) if(to[i]!=fa){
		dfs(to[i],x);
		Merge(x,to[i]);
	}
	
	a[x][0]++;
	for(int i=a[x][0];i>1;i--) a[x][i]=a[x][i-1];
	a[x][1]=w[x];
}

inline void calc(int x){
	int ans=0;
	for(int i=1;i<=n;i++) ans+=i*a[x][i];
	printf("%d\n",ans);
}

int main(){
	int uu, vv, root;
	while(scanf("%d%d",&n,&root)==2&&n&&root){
		init();
	    for(int i=1;i<=n;i++) scanf("%d",w+i);
	    for(int i=1;i<n;i++) scanf("%d%d",&uu,&vv),add(uu,vv),add(vv,uu);
	    dfs(root,-1),calc(root);
	}
	return 0;
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325081034&siteId=291194637