ZOJ2314Reactor Cooling(无源汇上下界可行流)
2016-05-22 11:08
453 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314
建图:
首先,建立一个超级源点s和超级汇点t。
然后,把所有原图中的边都加入到建立的新图中,容量为上限间下限。
再后,计算出一个d[i],表示编号为 i 的点所有流入的下限流量的和 减去 该点所有留出的下限流量和;如果d[i] > 0,那么就连一条从 s 到 i 容量为 d[i] 的边;如果d[i] < 0,那么就从 i 到 t 连一条容量为 -d[i] 的边;如果 d[i] == 0,就不用连边。
最后,计算 s 到 t 最大流。
注意,输出的时候只输出原图中的边,流量为计算出的流量加上流量下限。
代码:
建图:
首先,建立一个超级源点s和超级汇点t。
然后,把所有原图中的边都加入到建立的新图中,容量为上限间下限。
再后,计算出一个d[i],表示编号为 i 的点所有流入的下限流量的和 减去 该点所有留出的下限流量和;如果d[i] > 0,那么就连一条从 s 到 i 容量为 d[i] 的边;如果d[i] < 0,那么就从 i 到 t 连一条容量为 -d[i] 的边;如果 d[i] == 0,就不用连边。
最后,计算 s 到 t 最大流。
注意,输出的时候只输出原图中的边,流量为计算出的流量加上流量下限。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define maxn 300 #define maxm 20000 #define INF (1<<31)-1 using namespace std; int l[maxn] = {0}; struct Edge { int from, to, cap, flow; int weight; Edge(int u, int v, int c, int f, int w): from(u), to(v), cap(c), flow(f), weight(w) {} }; struct Dinic { int n, m, s, t; vector<Edge> edges; vector<int> G[maxn]; bool vis[maxn]; int d[maxn]; int p[maxn]; int a[maxn]; int num_Edge[maxm]; void init(int n, int m) { this->n = n; this->m = m; this->s = 0; this->t = n+1; for (int i=0; i<n; i++) { G[i].clear(); } edges.clear(); } void addEdge(int from, int to, int cap, int w = 1) { edges.push_back(Edge(from, to, cap, 0, w)); edges.push_back(Edge(to, from, 0, 0, w)); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); num_Edge = m-2; } int spfa() { memset(vis,0,sizeof(vis)); vis[s] = true; for (int i=0; i<=t; i++) d[i] = INF; d[s] = 0; p[s] = 0; a[s] = INF; /*for (int i=0; i<=n; i++) cout<<d[i]<<' ';*/ queue<int> Q; Q.push(s); d[s] = 0; vis[s] = true; while (!Q.empty()) { int x = Q.front(); Q.pop(); vis[x] = false; for (int i=0; i<G[x].size(); i++) { Edge& e = edges[G[x][i]]; if (e.cap>e.flow && d[e.to] > d[x]+e.weight) { d[e.to] = d[x]+e.weight; p[e.to] = G[x][i]; a[e.to] = min(a[x], e.cap-e.flow); if (!vis[e.to]) { Q.push(e.to); vis[e.to] = true; } } } } if (d[t] == INF) return 0; int u = t; while (u != s) { Edge e = edges[p[u]]; edges[p[u]].flow += a[t]; edges[p[u]^1].flow -= a[t]; u = edges[p[u]].from; } return a[t]; } int maxFlow() { int flow = 0; while (true) { int f = spfa(); if (!f) break; flow += f; } return flow; } void print(int m) { bool flag = true; for (int i=0; i<G[s].size(); i++) { Edge e = edges[G[s][i]]; if (e.flow < e.cap) { flag = false; break; } } if (flag) { cout<<"YES"<<endl; for (int i=1; i<=m; i++) cout<<edges[(i-1)*2].flow + l[i]<<endl; } else cout<<"NO"<<endl; } }; int main() { int t; cin>>t; while (t > 0) { t--; int n, m; Dinic a; scanf("%d%d",&n,&m); a.init(n,m); int d[maxn] = {0}; for (int i=1; i<=m; i++) { int u, v, c; scanf("%d%d%d%d",&u,&v,&l[i],&c); a.addEdge(u,v,c-l[i]); d[u] -= l[i]; d[v] += l[i]; } for (int i=1; i<=n; i++) { if (d[i] > 0) a.addEdge(0,i,d[i]); else if (d[i] < 0) a.addEdge(i,n+1,-d[i]); } int ans = a.maxFlow(); a.print(m); if (t > 0) cout<<endl; } return 0; }
相关文章推荐
- 跟angular2学一键开启项目--关于上个react-redux项目的一键调试
- 响应式编程框架ReactiveCocoa介绍与入门
- React Native的原生路由
- CSS Modules 关于CSS模块化的方法 基于React
- react native安装笔记
- 注册IRP_MJ_SHUTDOWN事件 基于ReactOS0303
- 学习React Native做开发的一般步骤
- mac 搭建react-native环境,无法run-android的问题
- 1.从Jquery 到 Reactjs 转变 遇到的十大神坑
- React Native的Navigator详解
- react笔记
- react native 选择手机照片页面英文问题
- React Native 解决iOS上键盘遮挡TextInput
- ReactOS-Freeldr注册表HIVE文件格式2
- ReactOS-Freeldr注册表HIVE文件格式
- React Native开发
- ReactNative 第六节 实战之ReactJS 组件和生命周期
- React Native踩坑Tip
- 【React】 React的优点+实现分页组件
- React入门实践之Todo List