hdu 3452 Bonsai(最小割)
2014-04-24 18:40
274 查看
题意:给出一棵树,每条边有一定的权值,现在要让根节点到达不了所有的叶子节点,问删掉的边的最小花费。
思路:没有树这样的条件的话就是个裸的最小割,其实加上树也没有难多少,只是需要注意一下建边的顺序,需要按照从root到各个节点的路径的方向建图,然后把所有的叶子节点连向汇点T,容量为inf,最后求最小割就行了。
代码:
思路:没有树这样的条件的话就是个裸的最小割,其实加上树也没有难多少,只是需要注意一下建边的顺序,需要按照从root到各个节点的路径的方向建图,然后把所有的叶子节点连向汇点T,容量为inf,最后求最小割就行了。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn=1000+10; const int maxm=5000+10; struct Edge { int to,cap,next; Edge(){} Edge(int to,int cap,int next):to(to),cap(cap),next(next){} }edges[maxm<<1]; int head[maxn],d[maxn],nEdge,n,S,T; vector<pair<int,int> >G[maxn]; void AddEdges(int from,int to,int cap) { edges[++nEdge]=Edge(to,cap,head[from]); head[from]=nEdge; edges[++nEdge]=Edge(from,0,head[to]); head[to]=nEdge; } bool BFS() { memset(d,0xff,sizeof(d)); queue<int>q; q.push(S); d[S]=0; while(!q.empty()) { int u=q.front();q.pop(); for(int k=head[u];k!=-1;k=edges[k].next) { Edge &e=edges[k]; if(d[e.to]==-1&&e.cap) { d[e.to]=d[u]+1; q.push(e.to); } } } return d[T]!=-1; } int DFS(int u,int a) { if(u==T||a==0) return a; int flow=0,f; for(int k=head[u];k!=-1;k=edges[k].next) { Edge &e=edges[k]; if(d[e.to]==d[u]+1&&(f=DFS(e.to,min(a,e.cap)))>0) { edges[k].cap-=f; edges[k^1].cap+=f; flow+=f;a-=f; if(a==0) return flow; } } d[u]=-1; return flow; } void build(int u,int fa) { int child=0; for(int i=0;i<(int)G[u].size();++i) { int v=G[u][i].first; if(v==fa) continue; child++; build(v,u); AddEdges(u,v,G[u][i].second); } if(child==0) AddEdges(u,T,inf); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int r; while(~scanf("%d%d",&n,&r)) { if(n==0&&r==0) break; memset(head,0xff,sizeof(head)); nEdge=-1; for(int i=0;i<=n;++i) G[i].clear(); int u,v,w; S=r,T=n+1; for(int i=1;i<n;++i) { scanf("%d%d%d",&u,&v,&w); G[u].push_back(make_pair(v,w)); G[v].push_back(make_pair(u,w)); } build(r,-1); int flow=0; while(BFS()) flow+=DFS(S,inf); if(n==1) flow=0; printf("%d\n",flow); } return 0; }
相关文章推荐
- HDU 3452 Bonsai(网络流之最小割)
- hdu 3452 Bonsai【最大流最小割-------Dinic】
- 【HDU】3452 Bonsai 最小割模板题
- hdu 3452 Bonsai 最小割
- HDU 3452 Bonsai(最小割)
- HDU - 3452 Bonsai 最小割
- hdu 3452 Bonsai 最小割
- HDU 3452 Bonsai(网络流之最小割)
- hdu 3452 Bonsai 最小割
- HDU 3452 Bonsai
- hdu 3452(最小割)
- hdu 3452(最小割)
- HDU 3452 Bonsai
- hdu 3452 Bonsai 求最少去掉多少权值的边使得所有的叶子节点和根节点断开连接
- hdu 3452 Bonsai(树形dp)另一种建树的方式
- HDU 3452 Bonsai
- hdu 3452 Bonsai(有点纠结的)
- HDU 3452 Bonsai
- hdu 3452 最小割
- HDU 3452 最小割 (树形dp)