• 【树形dp】Find Metal Mineral


    [HDU4003]Find Metal Mineral

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
    Total Submission(s): 3686    Accepted Submission(s): 1723

    Problem Description
    Humans have discovered a kind of new metal mineral on Mars which are distributed in point‐like with paths connecting each of them which formed a tree. Now Humans launches k robots on Mars to collect them, and due to the unknown reasons, the landing site S of all robots is identified in advanced, in other word, all robot should start their job at point S. Each robot can return to Earth anywhere, and of course they cannot go back to Mars. We have research the information of all paths on Mars, including its two endpoints x, y and energy cost w. To reduce the total energy cost, we should make a optimal plan which cost minimal energy cost.
     
    Input
    There are multiple cases in the input.
    In each case:
    The first line specifies three integers N, S, K specifying the numbers of metal mineral, landing site and the number of robots.
    The next n‐1 lines will give three integers x, y, w in each line specifying there is a path connected point x and y which should cost w.
    1<=N<=10000, 1<=S<=N, 1<=k<=10, 1<=x, y<=N, 1<=w<=10000.
     
    Output
    For each cases output one line with the minimal energy cost.
     
    Sample Input

    3 1 1
    1 2 1
    1 3 1
    3 1 2
    1 2 1
    1 3 1

     
    Sample Output
    3
    2
     
    Hint
    In the first case: 1->2->1->3 the cost is 3; In the second case: 1->2; 1->3 the cost is 2;
     
    Source
     
    题目大意:给出一颗带边权树,N个节点,根为S。现在有K个机器人要遍历这N个点,求最小花费?
    试题分析:依照以前的设计思路,还是dp[N][K]表示在节点i的子树中用去j个机器人状态。
         那么这样设计可不可行呢?我们来看一下转移方程:
           那么就需要将j=0单列出来讨论 dp[i][0]=sum(dp[i->son][0]+2*Cost[i->son]) 因为只有一个机器人,所以只能它自己走,结果一定。
                 j≠0时:     dp[i][j]=min(dp[i][j],dp[i->son][t]+t*Cost[i->son]+dp[i][j-t]);有多个机器人时,肯定让它们分开跑最优。
         dp[i][j]每次应该先加上dp[i->son][0]+2*Cost[i->son],因为可能用一个机器人遍历这颗子树。
     
    代码:
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<algorithm>
    using namespace std;
    
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    const int MAXN=100001;
    const int INF=999999;
    int N,S,K;
    int u,w,v;
    int Next[MAXN*2],Node[MAXN*2],Root[MAXN*2],Cost[MAXN*2];
    int dp[MAXN][12];
    int cnt;
    
    void addedge(int u,int v,int w){
    	cnt++;
    	Node[cnt]=v;
    	Cost[cnt]=w;
    	Next[cnt]=Root[u];
    	Root[u]=cnt;
    	return ;
    } 
    
    void dfs(int x,int fa){
    	int cnt=0;
    	for(int x1=Root[x];x1;x1=Next[x1]){
    		if(Node[x1]==fa) continue;
    		dfs(Node[x1],x);cnt++;
    	}
    	if(!cnt) {
    	    for(int i=0;i<=K;i++) dp[x][i]=0;
    		return ;
    	}
    	for(int x1=Root[x];x1;x1=Next[x1]){
    		if(Node[x1]==fa) continue;
    		int SON=Node[x1];
    		for(int k=K;k>=0;k--){
    			if(dp[x][k]==-1){
    				if(!k) dp[x][0]=dp[SON][0]+Cost[x1]*2;
    				else{
    					for(int t=1;t<=k;t++)
    					    if(dp[x][k]==-1||dp[x][k]>dp[SON][t]+t*Cost[x1])
    					        dp[x][k]=dp[SON][t]+t*Cost[x1];
    				}
    			} 
    			else{
    				if(!k) dp[x][k]+=(dp[SON][0]+Cost[x1]*2);
    				else{
    					dp[x][k]+=dp[SON][0]+2*Cost[x1];
    					for(int t=1;t<=k;t++){
    					    dp[x][k]=min(dp[x][k-t]+dp[SON][t]+t*Cost[x1],dp[x][k]);
    					}
    				}
    			}
    		}
    	}
    	return ;
    }
    
    int main(){
    	while(scanf("%d%d%d",&N,&S,&K)!=EOF){
    		cnt=0;
    		memset(Node,0,sizeof(Node));
    		memset(Root,0,sizeof(Root));
    		memset(Cost,0,sizeof(Cost));
    		memset(Next,0,sizeof(Next));
    		for(int i=1;i<N;i++){
    			u=read(),v=read(),w=read();
    		    addedge(u,v,w);
    		    addedge(v,u,w);
    		}
    		memset(dp,-1,sizeof(dp));
    		dfs(S,-1);
    		printf("%d
    ",dp[S][K]);
    	}
    }
  • 相关阅读:
    mouse_event模拟鼠标滚轮
    润乾报表配置技术路线
    建筑 物件 开心背单词 读句子,单词,字母,看图例, 翻译,看动画
    文字过渡动画,曲线过渡动画,,使用这个插件assign shape keys
    运动锻炼 开心背单词 读句子,单词,字母,看图例, 翻译,看动画,学英语,轻松背单词,简单背单词
    blender293 内置插件 精度绘画控件,PDT学习003,pdt tangents 切线
    日常用品 背单词 读句子 看图片 读单词 读字母 翻译, 看动画 学英语
    blender293 内置插件 精度绘画控件,PDT学习 precision drawing tools
    乔布斯 背单词 02 读句子 单词 字母 翻译,看动画 学英语 名言 我菜顾我在,我菜故我在,blender加python
    狐狸 和 乌鸦 英语 朗读句子 背单词
  • 原文地址:https://www.cnblogs.com/wxjor/p/7266791.html
Copyright © 2020-2023  润新知