POJ 3204 Ikki's Story I - Road Reconstruction(最小割+残余网络)
2015-09-05 16:51
507 查看
题目大意:给出一张有向图,现在要求你增大一条边的容量,使得最大流增大
解题思路:增大的边肯定是割边了,所以,先找到割边
接着枚举割边,增容,在残余网络上跑最大流,如果有流的话,就表示增加了改边可以使最大流增大
解题思路:增大的边肯定是割边了,所以,先找到割边
接着枚举割边,增容,在残余网络上跑最大流,如果有流的话,就表示增加了改边可以使最大流增大
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; const int MAXNODE = 1010; const int MAXEDGE = 100010; typedef int Type; const Type INF = 0x3f3f3f3f; struct Edge{ int u, v, next; Type cap, flow; Edge() {} Edge(int u, int v, Type cap, Type flow, int next) : u(u), v(v), cap(cap), flow(flow), next(next){} }; struct Dinic{ int n, m, s, t; Edge edges[MAXEDGE]; int head[MAXNODE]; bool vis[MAXNODE]; Type d[MAXNODE]; vector<int> cut; void init(int n) { this->n = n; memset(head, -1, sizeof(head)); m = 0; } void AddEdge(int u, int v, Type cap) { edges[m] = Edge(u, v, cap, 0, head[u]); head[u] = m++; edges[m] = Edge(v, u, 0, 0, head[v]); head[v] = m++; } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(s); d[s] = 0; vis[s] = 1; while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = head[u]; ~i; i = edges[i].next) { Edge &e = edges[i]; if (!vis[e.v] && e.cap > e.flow) { vis[e.v] = true; d[e.v] = d[u] + 1; Q.push(e.v); } } } return vis[t]; } Type DFS(int u, Type a) { if (u == t || a == 0) return a; Type flow = 0, f; for (int i = head[u]; ~i; i = edges[i].next) { Edge &e = edges[i]; if (d[u] + 1 == d[e.v] && (f = DFS(e.v, min(a, e.cap - e.flow))) > 0) { e.flow += f; edges[i ^ 1].flow -= f; flow += f; a -= f; if (a == 0) break; } } return flow; } Type Maxflow(int s, int t) { this->s = s; this->t = t; Type flow = 0; while (BFS()) flow += DFS(s, INF); return flow; } void Residue() { for (int i = 0; i < m; i++) edges[i].cap -= edges[i].flow; } void Clear() { for (int i = 0; i < m; i++) edges[i].flow = 0; } void Mincut() { cut.clear(); int ans = 0; for (int i = 0; i < m; i += 2) { if (vis[edges[i].u] && !vis[edges[i].v] && edges[i].cap > 0) cut.push_back(i); } } }dinic; int n, m; void solve() { int source = 0, sink = n - 1; dinic.init(sink + 1); int u, v, c; for (int i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v, &c); dinic.AddEdge(u, v, c); } dinic.Maxflow(source, sink); dinic.Mincut(); dinic.Residue(); int ans = 0; for (int i = 0; i < dinic.cut.size(); i++) { dinic.Clear(); Edge &e = dinic.edges[dinic.cut[i]]; e.cap += 10; int tmp = dinic.Maxflow(source, sink); if (tmp) ans++; e.cap -= 10; } printf("%d\n", ans); } int main() { while (scanf("%d%d", &n, &m) != EOF) solve(); return 0; }
相关文章推荐
- vuGen回放https录制出错
- TCP/IP(2)链路层
- Shell命令——网络
- sharepoint 2016 学习系列篇(6)-配置网站的备用网络映射
- HDU5007-Post Robot-2014西安网络赛(字符串水题)
- TCP协议疑难杂症解析
- 递归神经网络不可思议的有效性
- 笔试——数据库、网络、操作系统(Linux)
- 新手使用长按手势将网络图片保存至系统相册出现的问题
- linux常用的网络管理命令
- Internet采用哪种网络协议?该协议的主要层次结构?
- Linux命令学习(一)_网络
- TCP与UDP
- java网络通信TCP与UDP
- xutils中configCurrentHttpCacheExpiry()的用法
- 虚拟机完全克隆CentOS后配置网络
- Linux系统管理-(11)-网络配置ifcfg家族
- VM10安装CentOS6.5网络配置
- 黑马程序员java之网络通讯
- ubuntu下tcpdump总结