网络流强化-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现有的网络流模型,但 ...
随机推荐
- Codeforces 691E题解 DP+矩阵快速幂
题面 传送门:http://codeforces.com/problemset/problem/691/E E. Xor-sequences time limit per test3 seconds ...
- Appium+Python之元素定位和操作
一.常用识别元素的工具 uiautomatorviewer:Android SDK自带的一个工具,在tools目录下 二.元素定位 1.格式:find_element_by_定位方式(va ...
- 初学css list-style属性
网上很多css布局中会看到这样的一句:list-style:none: 那么list-style到底什么意思?中文即:列表样式:无: 其实它是一个简写属性,包含了所有列表属性,具体包含list-sty ...
- 5.MCScanX 与circos下载、安装、运用
一.MCSCAN 参考 :http://chibba.pgml.uga.edu/mcscan2/MCScanX.zip http://chibba.pgml.uga.edu/mcscan2/#tm ...
- SSM商城系统开发笔记-问题02- Error creating bean with name 'userController'
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean wit ...
- 在navcat中清空数据后,设置id归零方法
写后台完成后,需要清空Mysql数据库中的测试数据,但是后面新增的数据,一直是以原来所删除数据的最大id为增量基本,比如,对于一些id敏感的项,十分不便,如图 原有10条数据,清空后,新增一两条,手动 ...
- python 安装opencv及问题解决
正常安装模式 pip install opencv-python==3.4.5.20 pip install opencv-contrib-python==3.4.5.20 -i http://pyp ...
- [Luogu1436]棋盘分割(动态规划)
[Luogu1436]棋盘分割 题目背景 无 题目描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的两部分中的任意一块继续如此分割,这样割了(n-1)次后, ...
- oracle 汇编04
General-Purpose Instructions The general-purpose instructions perform basic data movement, memory ad ...
- 【Database】Mysql分布式集群学习笔记
一.sql 的基本操作 (2018年11月29日,笔记) (1)数据库相关操作 创建数据库.查看数据库.删除数据库 #. 创建数据库 create database mytest default ch ...