HDU 6214 Smallest Minimum Cut(求最小割的最少边数)
来源:互联网 发布:js div添加点击事件 编辑:程序博客网 时间:2024/05/21 13:23
题目大意:给定一个图,从s到t求最小割,要求最小割的边数最少,输出最少的边数。
解法:这其实就是一道原题,当时网络赛一搜就搜到了。
方法1:先跑一遍最大流,满流的边必定是某个集合的最小割的边(很好理解,每次找增广路的时候,这条路被限制的最大流量就是这条路上流量最小的边,这条边必定对答案有贡献)。此时遍历所有正向边,满流的边使其流量为1,不满流的边重新设定其流量为INF,网络有许多错误的博客在这里令反向边归0了,可以找出反例如:
这里反向边的绝对不能归零的,否则圈起来的那条边无法反向走一个流量,最后就会得到答案为2,事实上答案是3。此时跑一遍最大流就是答案。
方法2:加入边的时候每条边的流量为:原流量*(边数+1)+1。跑一边最大流,最后得到的流量mod(边数+1)就是答案。这个方法十分妙,假设原图中的最大流是flow,则这样处理后得到的流量为:flow * (边数+1) + B。B即为最少的边数。所以答案为最大流对(边数+1)取模。
我们对原图每条边都进行了+1处理,这个+1是不会影响到我们求最大流的,就像有一个高度为边数+1的杯子,由于你只有E条边,所以杯子永远都不会满,其他流量该对答案有贡献的依然会对答案有贡献的。网上有的博客说可以乘以一个大数,这个大数也必须是要大于等于边数+1的。
这里只给出方法1的代码。
代码如下:
#include<iostream>#include<cstring>#include<cstdio>#include<queue>const int maxn = 1005;const int maxm = 10005;const int INF = 0x3f3f3f3f;using namespace std;inline int read(){ int x=0,t=1,c; while(!isdigit(c=getchar()))if(c=='-')t=-1; while(isdigit(c))x=x*10+c-'0',c=getchar(); return x*t;}int head[maxn],cur[maxn],nx[maxm<<1],to[maxm<<1],flow[maxm<<1],ppp=0, val[maxm << 1];struct Dinic{ int dis[maxn]; int s, t; long long ans; void init() { memset(head, -1, sizeof(head)); ppp = 0; } void AddEdge(int u, int v, int c) { val[ppp] = c; to[ppp]=v;flow[ppp]=c;nx[ppp]=head[u];head[u]=ppp++;swap(u,v); to[ppp]=v;flow[ppp]=0;nx[ppp]=head[u];head[u]=ppp++; } bool BFS() { memset(dis, -1, sizeof(dis)); dis[s] = 1; queue<int> Q; Q.push(s); while(!Q.empty()) { int x = Q.front(); Q.pop(); for(int i = head[x]; ~i; i = nx[i]) { if(flow[i] && dis[to[i]] == -1) { dis[to[i]] = dis[x] + 1; Q.push(to[i]); } } } return dis[t] != -1; } int DFS(int x, int maxflow) { if(x == t || !maxflow){ ans += maxflow; return maxflow; } int ret = 0, f; for(int &i = cur[x]; ~i; i = nx[i]) { if(dis[to[i]] == dis[x] + 1 && (f = DFS(to[i], min(maxflow, flow[i])))) { ret += f; flow[i] -= f; flow[i^1] += f; maxflow -= f; if(!maxflow) break; } } return ret; } long long solve(int source, int tank) { s = source; t = tank; ans = 0; while(BFS()) { memcpy(cur, head, sizeof(cur)); DFS(s, INF); } return ans; }}dinic;void build() { for(int i = 0; i < ppp; i += 2) { if(flow[i] == 0) { flow[i] = 1; } else { flow[i] = INF; } }}int main() { int T; scanf("%d", &T); while(T--) { int n = read(),m = read(); int s = read(), t = read(); dinic.init(); while(m--) { int u = read(), v = read(), c = read(); dinic.AddEdge(u, v, c); } dinic.solve(s, t); build(); long long ans = dinic.solve(s, t); printf("%lld\n", ans); } return 0;}
阅读全文
0 0
- HDU 6214 Smallest Minimum Cut(求最小割的最少边数)
- hdu Smallest Minimum Cut 边数最少的最小割
- HDU 6214 Smallest Minimum Cut(网络流 最小割最少边数)
- HDU 6214 Smallest Minimum Cut(最小割的最少割边数)
- hdu-6214 Smallest Minimum Cut(最小割的最少边)
- HDU 6214 Smallest Minimum Cut【最小割的最小边数】
- HDU 6214 Smallest Minimum Cut (最小割最小割边)(两种算法的分析)
- hdu6214—Smallest Minimum Cut(最小割的最少割边)
- 2017 ACM/ICPC Asia Regional Qingdao Online HDU 6214 Smallest Minimum Cut(最小割的边数)
- HDU 6214 Smallest Minimum Cut 【最小割】
- HDU-6214 Smallest Minimum Cut(最小割)
- HDU 6214 Smallest Minimum Cut 最小割(isap)
- HDU 6214 Smallest Minimum Cut (最小割)
- Hdu 6214 Smallest Minimum Cut(最小割)
- HDU6214 Smallest Minimum Cut【最小割-最小边数】
- HDU 6214 Smallest Minimum Cut 2017青岛网赛1009(最小割最小割边)
- HDU6214 Smallest Minimum Cut 【最大流求最小割边】
- Hdu 6214 Smallest Minimum Cut【Dinic-最大流最小割】
- FTP 服务器的上传和下载
- 属性选择器
- Sublime text 2/3 中 Package Control 的安装与使用方法
- es6新增内容简单概览
- mui的使用
- HDU 6214 Smallest Minimum Cut(求最小割的最少边数)
- Google Dapper 大规模分布式系统的跟踪方案
- 我的CSDN
- python多线程在IO密集型情况下为什么会更快?
- wsdl2java无法生成客户端代码报错无法访问file
- 线段树plus
- web前端之添加过滤器
- 欢迎使用CSDN-markdown编辑器
- Spring多数据源导致配置失效