• UVA 10859 树形DP


    很明显的树形DP了,设状态dp[i][0],dp[i][1]。枚举子节点放或不放的两种状态。

    在此学到一种不同于一般处理的方法,题目要求被两灯照亮的边尽量多,反过来即被一灯照亮的尽量少设为e。又需要的灯尽量少设为v。

    设M是一个很大的数,则M*v+e即是所求。由于M很大,所以主导作用取决于v,只要v不同M*v+e一定不会相同。当v相同,被一灯照亮的尽量少即v此时发挥作用。所以DP时只需要保存这种状态即可。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    int dp[1050][2];
    bool vis[1050];
    vector<int>t[1050];
    
    const int M=2500;
    int n,m;
    
    void dfs(int u,int f){
    	vis[u]=true;
    	dp[u][1]=M;
    	dp[u][0]=0;
    	int sz=t[u].size();
    	for(int i=0;i<sz;i++){
    		if(t[u][i]!=f){
    			dfs(t[u][i],u);
    			dp[u][0]+=dp[t[u][i]][1]+1;
    			dp[u][1]+=dp[t[u][i]][0]<dp[t[u][i]][1]?dp[t[u][i]][0]+1:dp[t[u][i]][1];
    		}
    	}
    }
    
    
    int main(){
    	int T,u,v;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d",&n,&m);
    		for(int i=0;i<n;i++)
    		t[i].clear(),vis[i]=false;
    		for(int i=1;i<=m;i++){
    			scanf("%d%d",&u,&v);
    			t[u].push_back(v);
    			t[v].push_back(u);
    		}
    		int ans=0;
    		for(int i=0;i<n;i++){
    			if(!vis[i]){
    				dfs(i,-1);
    				ans+=min(dp[i][1],dp[i][0]);
    			}
    		}
    		printf("%d %d %d
    ",ans/M,m-ans%M,ans%M);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Express中间件简介
    Express中间件概念
    浏览器cookie插件
    node=day7
    cookie可视化操作工具---EditThisCookie
    node之cookie和session对比
    node通过session保存登录状态
    浅谈表单同步提交和异步提交
    node.js服务端存储用户密码md5加密
    jQuery的ajax里dataType预期服务器返回数据类型
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4546116.html
Copyright © 2020-2023  润新知