HDU 3452 Bonsai | 最小割
来源:互联网 发布:最大公约数c语言算法 编辑:程序博客网 时间:2024/06/06 11:43
这题让我很清楚得看到最小割的本质,实际就是用最小的代价,使得包含s的大S和包含t的大T分开。
最小代价就是所要求的最小割。
————————————————————————————————————————————————
题意:
给你一棵树,root根节点已经知道。每条边都有一个边权。让你用最小的代价使得根节点与叶子结点分开。
思路:
root节点作为源点s;
叶子节点连到汇点t,容量为INF;
其他节点就根据题目所给数据构建。
此外要找出哪个才是叶子结点,这个我用了dfs来搜。其实可以用一开始就用vecotr来保存邻接表,然后直接判断就可以得知。
————————————————————————————————————————————————
注意点:
流量可以为0,以及只有一个节点的情况。
————————————————————————————————————————————————
#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <queue>#include <vector>#define debug cout<<"debug"<<endl;using namespace std;const int MAXEDGE = 5*1e5+ 5;const int MAXN = 1010;const int INF = 0x3F3F3F3F;int n, r;struct Edge{ int to, cap, flow, next;};Edge edge[MAXEDGE];struct Dinic{ int s, t, pp; bool vis[MAXN]; int head[MAXN]; int d[MAXN], cur[MAXN]; Dinic(int ss, int tt) { s = ss, t = tt; pp = 0; memset(head, -1, sizeof(head)); memset(vis, false, sizeof(vis)); //一定要加! } void addEdge(int u, int v, int c) { edge[pp] = (Edge){v, c, 0, head[u]}; head[u] = pp++; edge[pp] = (Edge){u, 0, 0,head[v]}; head[v] = pp++; } void findLeaves(int u) //dfs { int cnt = 0; int next = head[u]; vis[u] = true; while(next != -1) { Edge &e = edge[next]; if(vis[e.to]) { next = e.next; continue; } //vis[e.to] = true; cnt ++; findLeaves(e.to); next = e.next; } if(cnt == 0) { //cout<<"u = "<<u<<endl; addEdge(u, t, INF); } } int getMaxFlow() { int res = 0; while(bfs()) { for(int i = 0;i < n + 5; i++) cur[i] = head[i]; //cout<<"res = "<<res<<endl; res += dfs(s, INF); } return res; } bool bfs() { memset(vis, false, sizeof(vis)); d[s] = 0; vis[s] = true; queue <int> q; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); int next = head[u]; while(next != -1) { Edge &e = edge[next]; if(!vis[e.to] && e.cap > e.flow) { d[e.to] = d[u] + 1; vis[e.to] = true; q.push(e.to); } next = e.next; } } return vis[t]; } int dfs(int u, int a) { if(u == t || a == 0) return a; int &next = cur[u]; int flow = 0, f; while(next != -1) { Edge &e = edge[next]; if(d[e.to] == d[u] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) { e.flow += f; edge[next^1].flow -= f; flow += f; a -= f; if(a == 0) break; } next = e.next; } //cout<<"flow = "<<flow<<endl; return flow; }};int main(){ while(scanf("%d%d",&n, &r), n&&r) { int u, v, c; int s = r, t = 0; Dinic dinic(s, t); for(int i = 0;i < n-1; i++) { scanf("%d%d%d",&u, &v, &c); dinic.addEdge(u, v, c); dinic.addEdge(v, u, c); } if(n == 1) { puts("0"); continue; } dinic.findLeaves(s); printf("%d\n",dinic.getMaxFlow()); } return 0;}
0 0
- hdu 3452 Bonsai 最小割
- hdu 3452 Bonsai(最小割)
- HDU 3452 Bonsai | 最小割
- hdu 3452 Bonsai 最小割
- 【HDU】3452 Bonsai 最小割模板题
- HDU 3452 Bonsai(最小割)
- HDU 3452 Bonsai(网络流之最小割)
- hdu 3452 Bonsai【最大流最小割-------Dinic】
- HDU 3452 Bonsai
- hdu 3452 最小割
- hdu 3452(最小割)
- hdu 3452 Bonsai(有点纠结的)
- hdu 3452 最小割 树形dp
- HDU 3452 最小割 (树形dp)
- hdu 3996 最小割
- HDU 3491 最小割
- HDU 3251 最小割
- hdu 3987 最小割
- P2P_NAT_UDP
- HDU 2064 汉诺塔III
- VS2010下安装MSDN
- 数字电路设计之奇偶分频的verilog实现
- 云计算/大数据/Hadoop2.0/MongoDB/数据挖掘分析/视频教程
- HDU 3452 Bonsai | 最小割
- 协同过滤技术
- Ubuntu 12.10 apt-get update 404 error问题解决方法
- 1407260920-hd-放大的X.cpp
- 找工作笔试面试那些事儿(14)---轻松一下,谈谈面试注意的点
- HDOJ_2017 字符串统计
- string[] args 和 string args[]两者的区别
- CSDN开源夏令营总结2014-07-26
- 灵感与文字