网络流强化-UVA10480
做这道题,自己先是想了好几种找被割的边的方法——都被否决了。
后来发现是最小割:只要一条边的两端在不同的点集里面就代表是被割掉的满流边(这些满流边的流量和等于最大流的流量与最小割的权值和)。
但是之前自己想了一个例子,
100
首先这个例子我自己误判了,以为最大流的流量是6,只要割掉1-4和3-2就行——就是脑子短路了,所以我还反过来怀疑双向边,再怀疑DFS和BFS寻找割集的方法,最后居然怀疑最大流和最小割的关系。
后来用了别人的代码,发现我自己解出来的最大流量值错了;但是用自己编的数据(在上面的基础上修改的):
3
她居然给我跑出来了三条容量为3的边,这就是为什么我怀疑最大流和最小割的关系的原因,后来发现人家在寻找源点能到的点集的时候,不仅要求边的剩余流量大于0,还要求基础的cap容量要大于0,这样的做法是错的。修改之后就好了。
AC代码:
//http://www.renfei.org/blog/isap.html 带解释的ISAP
//https://www.cnblogs.com/bosswnx/p/10353301.html 形式和我的比较相近的 ISAP
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxe 2048 //pay 双向边 一共10万条路 双向就是20万 反边就是40万
#define maxv 55 //pay
#define maxn 205 //pay
#define sc scanf
#define pt printf
#define rep(i,a,b) for(int i=(a);i<(b);++i)
const int inf = 0x3f3f3f3f;
int cg,sp,ins; //cg change sp是总流量 ins是加速回溯点
int N,M ,s,t;
int q[maxv],fro,rea;
typedef struct ed{
int v,nxt,cap; //dis
}ed;
ed e[maxe];
typedef struct cz{
int x,y; //dis
}cz;
cz ob[maxe];
int tp;
int tot,head[maxv],cur[maxv],vis[maxv],bk[maxv],d[maxv],num[maxv]; //
int mi(int a,int b) {return a<b?a:b;}
int mx(int a,int b) {return a>b?a:b;}
void add(int u,int v,int cap)
{
e[tot].v=v; e[tot].nxt=head[u];
/*e[tot].dis=dis;*/ e[tot].cap=cap;
head[u]=tot++; e[tot].v=u; e[tot].nxt=head[v];
/*e[tot].dis=-dis;*/ e[tot].cap=;
head[v]=tot++;
}
// 仅有一次的BFS为ISAP节省了不少时间
bool bfs()
{
//数组模拟queue
memset(vis, , sizeof(vis));
fro = rea = ;
q[rea] = t; ++rea;
vis[t] = ;
d[t] = ;
int u,v,i;
while (rea>fro)
{
u = q[fro]; ++fro;
for (i=head[u]; i!=-; i=e[i].nxt)
{
v=e[i].v;
if (!vis[v] && e[i^].cap )
{
vis[v] = true;
d[v] = d[u] + ;
q[rea] = v; ++rea;
}
}
}
return vis[s];
}
// 增广
int augment()
{
int flow = inf, i;
cg = t;
// 从汇点到源点通过 p 追踪增广路径, flow 为一路上最小的残量
while (cg != s) {
i = bk[cg];
if(flow>=e[i].cap)
{
flow = e[i].cap;
ins = e[i^].v;
//用来加速寻找,在最小流量断开的地方重新开始寻找
//嗯,等一下 我这个是从终点往起点寻找,而确定增光路径是从起点到终点
//那么起点是河流的上游,那么回溯的河段应该尽可能的往上游靠近
//所以应该将flow>e[i].cap的大于号改成大于等于号
}
cg = e[i^].v;
}
cg = t;
// 从汇点到源点更新流量
while (cg != s) {
i = bk[cg];
e[i].cap -= flow;
e[i^].cap += flow;
cg = e[i^].v;
}
return flow;
}
//由于每次修改层次的时候,都是在到剩下子节点的距离中挑选最短的加1 所以层次分明不会出现死循环
int max_flow()
{
int flow = ,i,u,v;
bool advanced;
if(bfs()==false) return ;
memset(num, , sizeof(num));
for (i = ; i <= N; ++i) ++num[d[i]];
//不一定是从s到t,你要知道统计每个层次的点的个数是全局统计的
u = s;
memcpy(cur, head, sizeof(head));
while (d[s] < N) //层次问题!!! 一定要保证t是最大的
//终点是0,那么起点所在层次最多是N-1 同理,不是d[s]<t
{
if (u == t)
{
flow += augment();
u = ins; //pay speed up
}
advanced = false;
for (i = cur[u]; i!=-; i=e[i].nxt)
{
v = e[i].v;
if (e[i].cap && d[u] == d[v] + )
{
advanced = true;
bk[v] = i;
cur[u] = i;
u = v;
break;
}
}
if (!advanced)
{ // retreat
int m = N; //层次问题!!! 一定要保证t是最大的
for (i = head[u]; i != -; i=e[i].nxt)
{
if (e[i].cap&&m>d[e[i].v])
{
cur[u] = i;
m = d[e[i].v];
}
}
if (--num[d[u]] == ) break; // gap 优化
++num[d[u] = m+];
//我以前一直在想 如果没有找到怎么办呢 现在发现原来找不到的话距离会被赋成N+1
if (u != s)
u = e[bk[u]^].v;
}
}
return flow;
} void init()
{
tot=;
memset(head,-,sizeof(head)); //pay
}
int main()
{
freopen("in.txt","r",stdin);
s=, t=,bk[]=-;
while(~sc("%d%d",&N,&M)&&N&&M)
{
tp=;
sp = ;
int i,w;
init();
for(i=;i<=M;++i)
{
sc("%d%d%d",&ob[tp].x,&ob[tp].y,&w);
add(ob[tp].x,ob[tp].y,w);
add(ob[tp].y,ob[tp].x,w);
++tp;
}
sp = max_flow();
//pt("%d\n",sp);
memset(vis, , sizeof(vis));
fro = rea = ;
q[rea] = s; ++rea;
vis[s] = ;
int u,v;
while (rea>fro)
{
u = q[fro]; ++fro;
for (i=head[u]; i!=-; i=e[i].nxt)
{
v=e[i].v;
if (!vis[v] && e[i].cap )
{
vis[v] = true;
q[rea] = v; ++rea;
}
}
}
for(i=;i<tp;++i) if(vis[ob[i].x]+vis[ob[i].y]==) pt("%d %d\n",ob[i].x,ob[i].y);
pt("\n");
}
return ;
}
UVA 10480
网络流强化-UVA10480的更多相关文章
- 网络流强化-HDU2732
第一次遇到加了“多余”的边会导致WA的——在我看来是很多余,见代码191行 之后会思考为什么,想出来再更. 问题弄明白了,如果你在连接边连了一条到没有柱子的点的边,这个没有柱子的点是不可能连到终点的, ...
- 网络流强化-HDU 3338-上下界限制最大流
题意是: 一种特殊的数独游戏,白色的方格给我们填1-9的数,有些带数字的黑色方格,右上角的数字代表从他开始往右一直到边界或者另外一个黑格子,中间经过的白格子的数字之和要等于这个数字:左下角的也是一样的 ...
- 网络流强化-HDU4280
数组没开够居然显示TLE而不是RE,自己觉得好的优化的方法没什么用…… //http://www.renfei.org/blog/isap.html 带解释的 //https://www.cnblog ...
- 网络流强化-POJ2516
k种货物分开求解最小费用最大流,主要减少了寻找最短路的时间. #include<queue> #include<cstdio> #include<cstring> ...
- UVA 10480 Sabotage (网络流,最大流,最小割)
UVA 10480 Sabotage (网络流,最大流,最小割) Description The regime of a small but wealthy dictatorship has been ...
- 【算法】【网络流24题】巨坑待填(成功TJ,有时间再填)
------------------------------------------------------------------------------------ 17/24 --------- ...
- [django]数据导出excel升级强化版(很强大!)
不多说了,原理采用xlwt导出excel文件,所谓的强化版指的是实现在网页上选择一定条件导出对应的数据 之前我的博文出过这类文章,但只是实现导出数据,这次左思右想,再加上网上的搜索,终于找出方法实现条 ...
- ITTC数据挖掘平台介绍(七)强化的数据库, 虚拟化,脚本编辑器
一. 前言 好久没有更新博客了,最近一直在忙着找工作,目前差不多尘埃落定.特别期待而且准备的都很少能成功,反而是没怎么在意的最终反而能拿到,真是神一样的人生. 言归正传,一直以来,数据挖掘系统的数据类 ...
- plain framework 1 网络流 缓存数据详解
网络流是什么?为什么网络流中需要存在缓存数据?为什么PF中要采用缓存网络数据的机制?带着这几个疑问,让我们好好详细的了解一下在网络数据交互中我们容易忽视以及薄弱的一块.该部分为PF现有的网络流模型,但 ...
随机推荐
- stl应用
http://codeforces.com/problemset/problem/1154/E E. Two Teams time limit per test 2 seconds memory li ...
- Mysql共享锁、排他锁、悲观锁、乐观锁
一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--间隙锁( ...
- 0基础入门 docker 部署 各种 Prometheus 案例 - 程序员学点xx 总集篇
目录 大家好, 学点xx 系列也推出一段时间了.虽然 yann 能力有限,但还是收到了很多鼓励与赞赏.对这个系列 yann 还是很喜欢的,特别是 Prometheus 篇,在期间经历公众号 100 篇 ...
- [SheetJS] js-xlsx模块学习指南
简介 SheetJS是前端操作Excel以及类似的二维表的最佳选择之一,而js-xlsx是它的社区版本. js-xlsx将注意力集中到了数据转换和导出上,所以它支持相当多种类的数据解析和导出.不仅仅局 ...
- JavaScript基础7——动态生成表格
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- vue axios 拦截器
前言 项目中需要验证登录用户身份是否过期,是否有权限进行操作,所以需要根据后台返回不同的状态码进行判断. 第一次使用拦截器,文章中如有不对的地方还请各位大佬帮忙指正谢谢. 正文 axios的拦截器分为 ...
- CentOS 6.5下源码安装LAMP(Linux+Apache+Mysql+Php)环境
---恢复内容开始--- 一.系统环境 系统平台:CentOS 6.5 (Final) Apache版本:httpd-2.2.31.tar.gz(最新版本2015-07-16) Mysql 版本:my ...
- React-请求篇
请求方式: (1)后台API:HttpPost [FromForm] UserRetisterDTO dto 前端请求: { body:qs.stringify(dto), header ...
- Express 2015 RC for Windows 10 安装
支持的操作系统 Windows 10 Technical Preview 硬件要求 1.6 GHz 或更快的处理器 1 GB RAM(如果在虚拟机上运行,则为 1.5 GB) 4 GB 可用硬盘空间 ...
- MySQL的删除语句
虽然现在数据库空间越来越大,但处理数据时候还是有要删除的时候,以下整理了一些最常用的删除语句. 分成两种 一个是删除指定数据,另一个删除所有数据. 一.删除指定数据 DELETE FROM 表名 WH ...