hdu3586Information Disturbing【树型dp】
2016-04-06 20:22
513 查看
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 communication routes can cover all of their soldiers. Information can exchange between any two soldiers by the communication routes. The number 1 soldier is
the total commander and other soldiers who have only one neighbour is the frontline soldier.
Your boss zzn ordered you to cut off some routes to make any frontline soldiers in the network cannot reflect the information they collect from the battlefield to the total commander( number 1 soldier).
There is a kind of device who can choose some routes to cut off . But the cost (w) of any route you choose to cut off can’t be more than the device’s upper limit power. And the sum of the cost can’t be more than the device’s life m.
Now please minimize the upper limit power of your device to finish your task.
Input
The input consists of several test cases.
The first line of each test case contains 2 integers: n(n<=1000)m(m<=1000000).
Each of the following N-1 lines is of the form:
ai bi wi
It means there’s one route from ai to bi(undirected) and it takes wi cost to cut off the route with the device.
(1<=ai,bi<=n,1<=wi<=1000)
The input ends with n=m=0.
Output
Each case should output one integer, the minimal possible upper limit power of your device to finish your task.
If there is no way to finish the task, output -1.
Sample Input
5 5
1 3 2
1 4 3
3 5 5
4 2 6
0 0
Sample Output
3
这题本来是要晚饭前搞定的,心不静啊==
说题意:切掉某些边使得每个叶子节点都不能与根节点相连,总共花费不能多于给定的m,问切掉的边里面最大边的最小值是多少?
感觉是:CodeForces 581F Contest Page 【树形dp】 与
hdu1561The more, The Better【树型dp 01背包】合并的解法,前一个题是有数组过渡,后一个题是把限制带入到了函数参数中。其实开始还以为要参考hdu1561The more,
The Better【树型dp 01背包 】 当中必须从根节点开始的写法。
既然说到了有限制,那么就应该想到数组的第二维[k]要用来表示最大边权<=k, 数组值表示最小被删边权和很容易理解。转移的时候也要注意,由于链式前向星本质是广搜,对于树来说可以利用这个性质计算以某一节点为根的子树根到下一层中间的边权值。也就是说,这个题的做法是一层一层切==
还有就是memset就WA memset只能给0 -1赋值,之前是巧合,没wa过,以后不要偷懒了==
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
long long dp[1002][1006];
int head[2005],tol,mx;
struct node
{
int to,next,w;
}tree[20000];
void init()
{
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)
{
tree[tol].to=v;tree[tol].w=w;tree[tol].next=head[u];head[u]=tol++;
}
void treedp(int u,int cc)
{
if(u!=1) for(int i=cc;i<=mx;i++) dp[u][i]=cc;
long long cost[1009]={0};
for(int i=head[u];i!=-1;i=tree[i].next)
{
int v=tree[i].to;
int w=tree[i].w;
treedp(v,w);
for(int j=1;j<=mx;j++)
cost[j]+=dp[v][j];
}
for(int i=1;i<=mx;i++)
{
if(cost[i]==0)continue;
dp[u][i]=min(dp[u][i],cost[i]);
}
}
int main()
{
//freopen("cin.txt","r",stdin);
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)break;
init();
mx=0;
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
mx=max(mx,w);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=mx;j++)
dp[i][j]=0x3f3f3f3f;
treedp(1,0);
int ans=-1;
for(int i=1;i<=mx;i++)
{
if(dp[1][i]<=m){ans=i;break;}
}
printf("%d\n",ans);
}
return 0;
}
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 communication routes can cover all of their soldiers. Information can exchange between any two soldiers by the communication routes. The number 1 soldier is
the total commander and other soldiers who have only one neighbour is the frontline soldier.
Your boss zzn ordered you to cut off some routes to make any frontline soldiers in the network cannot reflect the information they collect from the battlefield to the total commander( number 1 soldier).
There is a kind of device who can choose some routes to cut off . But the cost (w) of any route you choose to cut off can’t be more than the device’s upper limit power. And the sum of the cost can’t be more than the device’s life m.
Now please minimize the upper limit power of your device to finish your task.
Input
The input consists of several test cases.
The first line of each test case contains 2 integers: n(n<=1000)m(m<=1000000).
Each of the following N-1 lines is of the form:
ai bi wi
It means there’s one route from ai to bi(undirected) and it takes wi cost to cut off the route with the device.
(1<=ai,bi<=n,1<=wi<=1000)
The input ends with n=m=0.
Output
Each case should output one integer, the minimal possible upper limit power of your device to finish your task.
If there is no way to finish the task, output -1.
Sample Input
5 5
1 3 2
1 4 3
3 5 5
4 2 6
0 0
Sample Output
3
这题本来是要晚饭前搞定的,心不静啊==
说题意:切掉某些边使得每个叶子节点都不能与根节点相连,总共花费不能多于给定的m,问切掉的边里面最大边的最小值是多少?
感觉是:CodeForces 581F Contest Page 【树形dp】 与
hdu1561The more, The Better【树型dp 01背包】合并的解法,前一个题是有数组过渡,后一个题是把限制带入到了函数参数中。其实开始还以为要参考hdu1561The more,
The Better【树型dp 01背包 】 当中必须从根节点开始的写法。
既然说到了有限制,那么就应该想到数组的第二维[k]要用来表示最大边权<=k, 数组值表示最小被删边权和很容易理解。转移的时候也要注意,由于链式前向星本质是广搜,对于树来说可以利用这个性质计算以某一节点为根的子树根到下一层中间的边权值。也就是说,这个题的做法是一层一层切==
还有就是memset就WA memset只能给0 -1赋值,之前是巧合,没wa过,以后不要偷懒了==
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
long long dp[1002][1006];
int head[2005],tol,mx;
struct node
{
int to,next,w;
}tree[20000];
void init()
{
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)
{
tree[tol].to=v;tree[tol].w=w;tree[tol].next=head[u];head[u]=tol++;
}
void treedp(int u,int cc)
{
if(u!=1) for(int i=cc;i<=mx;i++) dp[u][i]=cc;
long long cost[1009]={0};
for(int i=head[u];i!=-1;i=tree[i].next)
{
int v=tree[i].to;
int w=tree[i].w;
treedp(v,w);
for(int j=1;j<=mx;j++)
cost[j]+=dp[v][j];
}
for(int i=1;i<=mx;i++)
{
if(cost[i]==0)continue;
dp[u][i]=min(dp[u][i],cost[i]);
}
}
int main()
{
//freopen("cin.txt","r",stdin);
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)break;
init();
mx=0;
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
mx=max(mx,w);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=mx;j++)
dp[i][j]=0x3f3f3f3f;
treedp(1,0);
int ans=-1;
for(int i=1;i<=mx;i++)
{
if(dp[1][i]<=m){ans=i;break;}
}
printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- 数据结构(左偏树,可并堆):BNUOJ 3943 Safe Travel
- 设计模式,,,一个程序猿应一生追求完美的东西
- 三种纯CSS方法实现等高列
- HDU2222 Keywords Search
- 进程调度
- 四则运算-安卓版
- 2016年4月4日作业
- 任务和回退栈
- 第四周项目5-递归求Fibnacci数(4)
- Bootstrap学习笔记—做一个简单的缩略图
- 快停下 劣质移动电源会把手机充坏
- 数据工程师常用的 Shell 命令
- MR程序的几种提交运行模式
- Android 高质量高压缩比图像压缩
- mysql删除同表重复记录保存id最小的记录
- 查找
- 线程和锁
- android studio 智能提示忽略大小写
- 第五周进度条
- 工厂模式