LightOJ 1177 - Angry Programmer【最大流最小割】
2015-09-02 19:33
369 查看
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1177
题意为求最小割。由最小割最大流定理 :最小割 ==》最大流
代码:
题意为求最小割。由最小割最大流定理 :最小割 ==》最大流
代码:
[code]#include <iostream> #include <algorithm> #include <set> #include <map> #include <string.h> #include <queue> #include <sstream> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <string> using namespace std; const int MAXN = 1010;//点数的最大值 const int MAXM = 400100;//边数的最大值 const int INF = 0x3f3f3f3f; struct Edge { int to, next, cap, flow; }edge[MAXM];//注意是MAXM int tol; int head[MAXN]; int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN]; void init() { tol = 0; memset(head, -1, sizeof(head)); } //加边,单向图三个参数,双向图四个参数 void addedge(int u, int v, int w, int rw = 0) { edge[tol].to = v; edge[tol].cap = w; edge[tol].next = head[u]; edge[tol].flow = 0; head[u] = tol++; edge[tol].to = u; edge[tol].cap = rw; edge[tol].next = head[v]; edge[tol].flow = 0; head[v] = tol++; } //输入参数:起点、终点、点的总数 //点的编号没有影响,只要输入点的总数 int sap(int start, int end, int N) { memset(gap, 0, sizeof(gap)); memset(dep, 0, sizeof(dep)); memcpy(cur, head, sizeof(head)); int u = start; pre[u] = -1; gap[0] = N; int ans = 0; while (dep[start] < N) { if (u == end) { int Min = INF; for (int i = pre[u]; i != -1; i = pre[edge[i ^ 1].to]) if (Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow; for (int i = pre[u]; i != -1; i = pre[edge[i ^ 1].to]) { edge[i].flow += Min; edge[i ^ 1].flow -= Min; } u = start; ans += Min; continue; } bool flag = false; int v; for (int i = cur[u]; i != -1; i = edge[i].next) { v = edge[i].to; if (edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u]) { flag = true; cur[u] = pre[v] = i; break; } } if (flag) { u = v; continue; } int Min = N; for (int i = head[u]; i != -1; i = edge[i].next) if (edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if (!gap[dep[u]])return ans; dep[u] = Min + 1; gap[dep[u]]++; if (u != start) u = edge[pre[u] ^ 1].to; } return ans; } int n, m; int cost[100]; int main() { int t, cases = 1; scanf("%d",&t); while (t--) { init(); scanf("%d%d", &n, &m); for (int i = 2;i < n;i++) scanf("%d", &cost[i]); for (int i = 2;i < n;i++) addedge(i, i + n, cost[i]); addedge(1, n + 1, 100000000); addedge(n, n*n, 100000000); int a, b, c; while (m--) { scanf("%d%d%d", &a, &b, &c); addedge(a + n, b, c); addedge(b + n, a, c); } int ans = sap(1, n, n * 2); printf("Case %d: %d\n", cases++, ans); } return 0; }
相关文章推荐
- ffmpeg H264 decode for Android Native Surface
- 安卓webview快速加载网页研究提速(二级加速)
- 到底热爱编程(programme)吗?
- JPEG编码(一)
- hdu1057
- 线程同步——死锁及举例
- seajs的那些事儿
- Material Design学习笔记(一)
- HDU 1010 Tempter of the Bone 深搜+奇偶剪枝
- 【window10下python的对elcel表格操作xlrd和xlwt模块的下载与安装及基本的使用】
- select函数的并发限制和 poll 函数应用举例
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) ( 莫队 )
- 【bzoj3668】【noi 2014】【起床困难综合症】【贪心】
- HDU 5159 Card(DP+组合数啊)
- java并发编程第六章(7)生成并发编程随机数
- [leetcode 19] Remove Nth Node From End of List
- Hadoop FS Shell命令大全
- CF_318_Div.2 Bear and Elections(二分||暴力枚举)
- mybatis-mybatis主配置文件
- 黑马程序员之网络编程