5 5 1 3 2 1 4 3 3 5 5 4 2 6 0 0
3
题意:切断一定的边,使得所有叶子节点与根节点断开,限制条件是断开的边权之和小于某一值,且每一条边权小于某一值x,求x的最小值。
一看题就知道是二分+树形dp判断可行性, INF上界不能太大,否则会溢出,因为这个wa好多次。
代码:
/* *********************************************** Author :xianxingwuguan Created Time :2014-2-6 16:15:10 File Name :1.cpp ************************************************ */ #pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #include <limits.h> #include <string> #include <time.h> #include <math.h> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define INF 1000000 #define eps 1e-8 #define pi acos(-1.0) typedef long long ll; const int maxn=4009; int head[maxn],tol; struct node{ int next,to,val; node(){}; node(int _next,int _to,int _val):next(_next),to(_to),val(_val){} }edge[5*maxn]; void add(int u,int v,int val){ edge[tol]=node(head[u],v,val); head[u]=tol++; } int dfs(int u,int fa,int num){ int sum=0,flag=0; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(v==fa)continue; int tt=dfs(v,u,num); if(tt>edge[i].val&&edge[i].val<=num) tt=edge[i].val; sum+=tt; flag=1; } if(!flag)return INF; return sum; } int main() { //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); int i,j,k,m,n; while(~scanf("%d%d",&n,&m)){ if(n==0||m==0)break; memset(head,-1,sizeof(head));tol=0; int l=1,r=1010; for(i=1;i<n;i++){ int p; scanf("%d%d%d",&j,&k,&p); add(j,k,p); add(k,j,p); } int ans=-1; while(l<=r){ int mid=(l+r)>>1; if(dfs(1,1,mid)<=m) ans=mid,r=mid-1; else l=mid+1; } cout<<ans<<endl; //cout<<dfs(1,-1,3)<<" "<<dfs(1,-1,4)<<endl; } return 0; }
原文:http://blog.csdn.net/xianxingwuguan1/article/details/18951369