ACM/ICPC 之 网络流入门-Ford Fulkerson与SAP算法(POJ1149-POJ1273)
第一题:按顾客访问猪圈的顺序依次构图(顾客为结点),汇点->第一个顾客->第二个顾客->...->汇点
//第一道网络流
//Ford-Fulkerson
//Time:47Ms Memory:276K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std; #define MAXN 105 //顾客
#define MAXM 1005 //猪圈
#define INF 0x3f3f3f3f struct Arc {
int c, f;
}e[MAXN][MAXN]; int n, m;
int s, t;
int pig[MAXM], last[MAXM]; //last[]:猪圈当前顾客(0为源点,n+1为汇点)
int pre[MAXN]; //1.从哪一个结点
int alpha[MAXN]; //2.可改进量 void ford() //ford fulkerson
{
alpha[s] = INF; //源点可改进量无限
while (1) { //多次标号
memset(pre, -1, sizeof(pre)); //初始标号
queue<int> q;
q.push(s);
while (!q.empty() && pre[t] == -1) {
int cur = q.front(); q.pop();
for (int i = 1; i <= t; i++)
{
int tmp;
//tmp 为非0可保证邻接且保证有剩余流量
if (pre[i] == -1 && (tmp = e[cur][i].c - e[cur][i].f))
{
pre[i] = cur;
q.push(i);
alpha[i] = min(alpha[cur], tmp);
}
}
}
if (pre[t] == -1) return; //未找到增广路
for (int i = pre[t], j = t; i != -1; j = i, i = pre[i])
{
e[i][j].f += alpha[t];
e[j][i].f = -e[i][j].f;
}
} } int main()
{
//freopen("in.txt", "r", stdin); memset(last, 0, sizeof(last));
memset(e, 0, sizeof(e));
scanf("%d%d", &m, &n);
s = 0; t = n + 1;
for (int i = 1; i <= m; i++)
scanf("%d", &pig[i]);
for (int i = 1; i <= n; i++)
{
int num; //钥匙数
scanf("%d", &num);
while (num--) {
int pn;
scanf("%d", &pn);
if (last[pn] == 0)
e[last[pn]][i].c += pig[pn];
else e[last[pn]][i].c = INF;
last[pn] = i;
}
scanf("%d", &e[i][t].c);
} ford(); int maxFlow = 0;
for (int i = 1; i < t; i++)
maxFlow += e[i][t].f;
printf("%d\n", maxFlow); return 0;
}
第二道:最短增广路(SAP)算法,dinic算法前身,与dinic不同的是需要多次采用BFS进行构建层次网络,题目本身较直接。
//网络流
//一般最短增广路算法-Dinic算法的前身
//Time:16Ms Memory:676K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std; #define MAX 205
#define INF 0x3f3f3f3f struct Arc {
int c, f;
}e[MAX][MAX]; int n, m;
int s, t;
int pre[MAX];
int res[MAX][MAX]; //残留网络->层次网络
bool v[MAX]; void bfs()
{
while (1) //多次BFS寻找增广路
{
memset(v, false, sizeof(v));
memset(res, 0, sizeof(res));
memset(pre, 0, sizeof(pre));
queue<int> q;
q.push(s); v[s] = true;
while (!q.empty() && pre[t] == 0)
{ //BFS构造层次网络
int cur = q.front(); q.pop();
for (int i = 1; i <= n; i++)
{
if (!v[i]) {
int tmp = e[cur][i].c - e[cur][i].f;
if (tmp > 0) { //正向有残留容量
res[cur][i] = tmp;
pre[i] = cur;
q.push(i); v[i] = true;
}
else if (e[i][cur].f > 0) { //反向有流量
res[cur][i] = e[i][cur].f;
pre[i] = cur;
q.push(i); v[i] = true;
}
}
}
}
if (pre[t] == 0) return;
int minroad = INF; //最小可改进量
for (int i = t; i != s; i = pre[i])
minroad = min(minroad, res[pre[i]][i]);
for (int i = t; i != s; i = pre[i])
{
if (e[pre[i]][i].c - e[pre[i]][i].f > 0)
e[pre[i]][i].f += minroad;
else if (e[i][pre[i]].f > 0)
e[i][pre[i]].f -= minroad;
} }
} int main()
{
//freopen("in.txt", "r", stdin); while (~scanf("%d%d", &m, &n))
{
memset(e, 0, sizeof(e));
int u, v, c;
for (int i = 0; i < m; i++)
{
scanf("%d%d%d", &u, &v, &c);
e[u][v].c += c;
} s = 1; t = n;
bfs(); int maxFlow = 0;
for (int i = 1; i < n; i++)
maxFlow += e[i][t].f;
printf("%d\n", maxFlow);
} return 0;
}
ACM/ICPC 之 网络流入门-Ford Fulkerson与SAP算法(POJ1149-POJ1273)的更多相关文章
- ACM/ICPC 之 网络流入门-EK算法(参考模板)(POJ1273)
基于残留网络与FF算法的改进-EK算法,核心是将一条边的单向残留容量的减少看做反向残留流量的增加. //网络流 //EK算法 //Time:16Ms Memory:348K #include<i ...
- ACM/ICPC 之 计算几何入门-叉积-to left test(POJ2318-POJ2398)
POJ2318 本题需要运用to left test不断判断点处于哪个分区,并统计分区的点个数(保证点不在边界和界外),用来做叉积入门题很合适 //计算几何-叉积入门题 //Time:157Ms Me ...
- ACM/ICPC 之 网络流-拆点构图(POJ2391)
需要直接到达,因此源点经过三条边后必须要达到汇点,但为了保证网络流的正确性(路径可反悔),因此不可限制层次网络的最高层次为3,最好的方法既是让所有点拆分成两个点,一个点从汇点进入,一个点通向汇点,任意 ...
- ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)
两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可 ...
- HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)
Barricade Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- ACM - ICPC World Finals 2013 C Surely You Congest
原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 试题来源 ACM/ICPC World Fin ...
- 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)
队名:Unlimited Code Works(无尽编码) 队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...
- 2016 ACM ICPC Asia Region - Tehran
2016 ACM ICPC Asia Region - Tehran A - Tax 题目描述:算税. solution 模拟. B - Key Maker 题目描述:给出\(n\)个序列,给定一个序 ...
- 2017 ACM ICPC Asia Regional - Daejeon
2017 ACM ICPC Asia Regional - Daejeon Problem A Broadcast Stations 题目描述:给出一棵树,每一个点有一个辐射距离\(p_i\)(待确定 ...
随机推荐
- Asp.Mvc中的text实现 辅助用户输入 灰色字体
在开发Web应用程序中经常需要用户在文本框输入信息,为了提高程序人性化设置以及用户体验效果常常需要在文本框中显示灰色字体辅助用户输入 如:
- Junit使用教程 转
几乎所有程序员都听说过Junit的大名,但不知真正懂得运用它的人有多少,我便是其中的一个小白. 知道Junit是用来测试的,但却把“宝刀”当成了“菜刀”用.为了从此不再菜鸟,特此总结整理了下Junit ...
- cmd /c和cmd /k 解释,附★CMD命令★ 大全
cmd /c和cmd /k http://leaning.javaeye.com/blog/380810 java的Runtime.getRuntime().exec(commandStr)可以调用执 ...
- jQuery EasyUI API 中文文档 - ValidateBox验证框
jQuery EasyUI API 中文文档 - ValidateBox验证框,使用jQuery EasyUI的朋友可以参考下. 用 $.fn.validatebox.defaults 重写了 d ...
- Method Swizzling (方法调配)
Method Swizzling是改变一个selector的实际实现的技术.通过这一技术,我们可以在运行时通过修改类的分发表中selector对应的函数,来修改方法的实现. 例如,我们想跟踪在程序中每 ...
- VisualStudio基本使用(1)-显示行号
"工具"-"选项"-"文本编辑器"-"C/C++"-"常规",勾选"行号"复选框 ...
- 【11-23】window常用知识
tips msconfig :管理应用程序加载启动项,也可以通过我的计算机查看 service.msc :管理windows本地服务 命令行:net start :显示所有启动的服务,不加分号 net ...
- vim查找替换
http://www.cnblogs.com/ltang/articles/2034291.html %: 表示百分百,表示所有 行的意思... 如果不指定行号, 则表示当前行; g: 表示一行中的所 ...
- 简单实用的PHP防注入类实例
这篇文章主要介绍了简单实用的PHP防注入类实例,以两个简单的防注入类为例介绍了PHP防注入的原理与技巧,对网站安全建设来说非常具有实用价值,需要的朋友可以参考下 本文实例讲述了简单实用的PHP防注 ...
- python简明手册学习
1.行末单独一个反斜杠表示字符串在下一行继续,而不是开始一个新的行. >>> "This is the first sentence.\ ... This is the s ...