zoukankan      html  css  js  c++  java
  • BZOJ_1369_[Baltic2003]Gem_树形DP

    BZOJ_1369_[Baltic2003]Gem_树形DP

    Description

    给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相临的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小。

    Input

    先给出一个数字N,代表树上有N个点,N<=10000 下面N-1行,代表两个点相连

    Output

    最小的总权值

    Sample Input

    10
    7 5
    1 2
    1 7
    8 9
    4 1
    9 7
    5 6
    10 2
    9 3

    Sample Output

    14


    分析:

    设f[i][j]为第i个点染色为j的最先花费,从子树上转移。

    但是N^3肯定是过不去的。

    不难发现权值不需要那么多,实际上最多logn种权值。

    直接转移即可。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 10050
    int head[N],to[N<<1],nxt[N<<1],cnt;
    int n,f[N][10];
    inline void add(int u,int v) {
    	to[++cnt]=v;
    	nxt[cnt]=head[u];
    	head[u]=cnt;
    }
    void dfs(int x,int y) {
    	int i,j,k;
    	for(i=1;i<=5;i++) f[x][i]=i;
    	for(i=head[x];i;i=nxt[i]) {
    		if(to[i]!=y) {
    			dfs(to[i],x);
    			for(j=1;j<=5;j++) {
    				int minf=1<<30;
    				for(k=1;k<=5;k++) {
    					if(j!=k) minf=min(minf,f[to[i]][k]);
    				}
    				f[x][j]+=minf;
    			}
    		}
    	}
    }
    int main() {
    	scanf("%d",&n);
    	int	i,x,y;
    	for(i=1;i<n;++i){
    		scanf("%d%d",&x,&y);
    		add(x,y);
    		add(y,x);
    	}
    	dfs(1,0);
    	int ans=1<<30;
    	for(i=1;i<=5;i++) ans=min(ans,f[1][i]);
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    spring-pool.xml
    spring-jmx.xml
    spring-common.xml
    applicationContext.xml
    spring-webservice.xml
    webservice统一认证
    jdbc.properties
    oracle,mysql分页
    springmvc-servlet.xml
    四、用“”或构造函数创建Java的String区别
  • 原文地址:https://www.cnblogs.com/suika/p/8678130.html
Copyright © 2011-2022 走看看