HDU 3452 Bonsai
可以树形DP,也可以用网络流(最大流=最小割)
用树形DP的话,这题就是
#include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<map> #include<vector> #include<string> #include<algorithm> #include<iostream> using namespace std; int n,root; const int maxn=1000+10; struct Edge { int to; int val; Edge (int u,int v){to=u;val=v;} }; vector<Edge>tree[maxn]; bool vis[maxn]; int dp[maxn]; void init() { for(int i=0;i<=n;i++) tree[i].clear(); memset(vis,0,sizeof vis); memset(dp,-1,sizeof dp); } void read() { for(int i=1;i<=n-1;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); Edge e1(v,w); Edge e2(u,w); tree[u].push_back(e1); tree[v].push_back(e2); } } void dfs(int now,int lim) { bool fail=1; for(int i=0;i<tree[now].size();i++) if(!vis[tree[now][i].to]) fail=0; if(fail) return; bool x=0; int sum=0; for(int i=0;i<tree[now].size();i++) { if(!vis[tree[now][i].to]) { vis[tree[now][i].to]=1; dfs(tree[now][i].to,lim); if(dp[tree[now][i].to]!=-1) sum=sum+min(tree[now][i].val,dp[tree[now][i].to]); else { if(tree[now][i].val<=lim) sum=sum+tree[now][i].val; else x=1; } } } if(!x) dp[now]=sum; } bool work(int lim) { memset(dp,-1,sizeof dp); memset(vis,0,sizeof vis); vis[root]=1; dfs(root,lim); if(n==1) dp[root]=0; printf("%d\n",dp[root]); return 1; } int main() { while(~scanf("%d%d",&n,&root)) { if(!n&&!root) break; init(); read(); work(2000); } return 0; }