您的位置:首页 > 其它

HDU3586 Information Disturbing(树形DP)

2016-03-24 20:13 183 查看
题目大概说一棵树有边权,要删掉一些边,使叶子到达不了树根1且删掉边的权和小于等于m,问删掉边中最大权的最小值能是多少。

考虑问题规模,与转移的时间复杂度,用这么个状态dp:

dp[u][k]表示在u结点为根的子树中,使其叶子到达不了根的,删掉边的最大权小于等于k的最小被删边权和

转移略蛋疼,初始值的设定之类的感觉有点不统一。。反正最后感觉自己写得有点挫。。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define INF 1100000
#define MAXN 1111
struct Edge{
int v,w,next;
}edge[MAXN<<1];
int NE,head[MAXN];
void addEdge(int u,int v,int w){
edge[NE].v=v; edge[NE].w=w; edge[NE].next=head[u];
head[u]=NE++;
}
long long d[MAXN][1001];
int mx;
void dp(int u,int w){
if(u!=1){
for(int i=w; i<=mx; ++i) d[u][i]=w;
}
long long tmp[1001]={0};
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
dp(v,edge[i].w);
for(int j=1; j<=mx; ++j){
tmp[j]+=d[v][j];
}
}
for(int i=1; i<=mx; ++i){
if(tmp[i]==0) continue;
d[u][i]=min(d[u][i],tmp[i]);
}
}
int main(){
int n,m,a,b,c;
while(~scanf("%d%d",&n,&m) && (n||m)){
NE=0;
memset(head,-1,sizeof(head));
mx=0;
for(int i=1; i<n; ++i){
scanf("%d%d%d",&a,&b,&c);
addEdge(a,b,c);
mx=max(mx,c);
}
for(int i=1; i<=n; ++i){
for(int j=1; j<=mx; ++j) d[i][j]=INF;
}
dp(1,0);
int res=-1;
for(int i=1; i<=mx; ++i){
if(d[1][i]<=m){
res=i;
break;
}
}
printf("%d\n",res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: