HDU-3586 Information Disturbing(树形DP+删边)

题目大意:一棵有n个节点的有根树,1为根节点,边带权,表示删掉这条边的代价。现在要删掉一些边,使叶子节点不能到达根节点。但是,每次删除的边的代价不能超过limit,删掉的边的总代价不能超过m,求最小的limit的可能取值。

题目分析:二分枚举limit,定义状态dp(u)表示将u与它管辖的叶子节点失去联系所需要的总代价,则:

dp(u)+=min(dp(son),e[i].w),e[i].w<=limit;

dp(u)+=dp(son)  e[i].w>limit;

代码如下:

# include<iostream>
# include<cstdio>
# include<cstring>
# include<vector>
# include<queue>
# include<list>
# include<set>
# include<map>
# include<string>
# include<cmath>
# include<cstdlib>
# include<algorithm>
using namespace std;
# define LL long long

const int N=1005;
const int INF=1000001;

struct Edge
{
	int w,to,nxt;
};
Edge e[N];
int n,m;
int du[N];
int maxn,cnt;
int dp[N];
int head[N];

void add(int u,int v,int w)
{
	e[cnt].to=v;
	e[cnt].w=w;
	e[cnt].nxt=head[u];
	head[u]=cnt++;
}

void init()
{
	int a,b,c;
	cnt=maxn=0;
	memset(du,0,sizeof(du));
	memset(head,-1,sizeof(head));
	for(int i=1;i<n;++i){
		scanf("%d%d%d",&a,&b,&c);
		++du[a];
		++du[b];
		maxn=max(maxn,c);
		add(a,b,c);
		add(b,a,c);
	}
}

void dfs(int u,int fa,int limit)
{
	//cout<<u<<endl;
	if(du[u]==1&&u!=1){
		dp[u]=INF;
		return ;
	}
	dp[u]=0;
	for(int i=head[u];i!=-1;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa) continue;
		dfs(v,u,limit);
		if(e[i].w>limit)
			dp[u]+=dp[v];
		else
			dp[u]+=min(dp[v],e[i].w);
	}
}

int solve()
{
	if(n==1)
		return 0;
	int l=1,r=maxn+1;
	while(l<r){
		int mid=l+(r-l)/2;
		dfs(1,-1,mid);
		if(dp[1]>m)
			l=mid+1;
		else
			r=mid;
	}
	dfs(1,-1,r);
	if(dp[1]>m) return -1;
	return r;
}

int main()
{
	//新的主题
	while(~scanf("%d%d",&n,&m)&&(n+m))
	{
		init();
		printf("%d\n",solve());
	}
	return 0;
}

  

时间: 2024-08-07 08:40:14

HDU-3586 Information Disturbing(树形DP+删边)的相关文章

HDU 3586.Information Disturbing 树形dp

Information Disturbing Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 3205    Accepted Submission(s): 1137 Problem Description In the battlefield , an effective way to defeat enemies is to bre

HDU 3586 Information Disturbing 树形DP+二分

Information Disturbing Problem Description In the battlefield , an effective way to defeat enemies is to break their communication system.The information department told you that there are n enemy soldiers and their network which have n-1 communicati

HDU 3586 Information Disturbing(二分+树形dp)

http://acm.split.hdu.edu.cn/showproblem.php?pid=3586 题意: 给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超过上限limit,问在保证总费用<=m下的最小的limit. 思路: 对于上限limit我们可以二分查找.然后就是树形dp,看代码就可以理解的. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring>

hdu 3586 Information Disturbing (树形dp)

Information Disturbing Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 1722    Accepted Submission(s): 641 Problem Description In the battlefield , an effective way to defeat enemies is to bre

HDU 3586 Information Disturbing

二分+树形DP验证. 答案是通过二分查找得到的,对于每一次二分到的值,进行验证,是否可行. 可以用树形DP来求解所有叶子节点不能向根节点传送消息的最小费用,dp[i] 表示 节点i 的子树的叶子结点都不能向i传送消息的最小费用,这样很容易递推. #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<map> #include<vector>

[hdu3586]Information Disturbing树形dp+二分

题意:给出一棵带权无向树,以及给定节点1,总约束为$m$,找出切断与所有叶子节点联系每条边所需要的最小价值约束. 解题关键:二分答案,转化为判定性问题,然后用树形dp验证答案即可. dp数组需要开到ll,如果用设inf的解法. 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e6+7; 5 const int inf=0x3f3f3f3f; 6 struct e

HDU 3586 Information Disturbing (二分+树形dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3586 给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线.现要切断前线和司令部的联系,每次切断边的费用不能超过上限limit,问切断所有前线与司令部联系所花费的总费用少于m时的最小limit.1<=n<=1000,1<=m<=10^6 dp[i]表示i节点为root的这个子树所破坏的最少费用,if(cost[i]

HDU 3586 Information Disturbing (树形DP,二分)

题意: 给定一个敌人的通信系统,是一棵树形,每个节点是一个敌人士兵,根节点是commander,叶子是前线,我们的目的是使得敌人的前线无法将消息传到commander,需要切断一些边,切断每条边需要一定的power,而我们有一台具有m点power的机器,问在使用此机器切断敌人通信系统的情况下,使得所切断边的最大边权达到最小是多少?(m<=100w,n<=1000) 思路: 其实就是要求所切断的边的最小瓶颈边.由于m比较大,不好枚举或者DP.但是他们具有线性的关系,就是瓶颈边越大,肯定越容易有解

HDU3585 Information Disturbing 树形dp+二分

http://acm.split.hdu.edu.cn/showproblem.php?pid=3586 题意 : 给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超过上限limit,问在保证总费用<=m下的最小的limit. 显然最小的总费用和最小的limit不能同时维护,那么只能在dfs中维护一个然后另一个用特殊的(朗诵)技巧解决-- emmmmmmmmm--说白了就是二分求最小的limit,然后就没有下面了. 算是普通难度,只要知道二分就很好写,虽然我开

HDU 1011 Starship Troopers(树形DP)

Starship Troopers Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 62   Accepted Submission(s) : 12 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description You, the leader of