网络流SAP+gap+弧优化算法
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 54962 | Accepted: 20960 |
Description
clover patch is never covered in water. Instead, the water is drained to a nearby stream. Being an ace engineer, Farmer John has also installed regulators at the beginning of each ditch, so he can control at what rate water flows into that ditch.
Farmer John knows not only how many gallons of water each ditch can transport per minute but also the exact layout of the ditches, which feed out of the pond and into each other and stream in a potentially complex network.
Given all this information, determine the maximum rate at which water can be transported out of the pond and into the stream. For any given ditch, water flows in only one direction, but there might be a way that water can flow in a circle.
Input
for those ditches. Intersection 1 is the pond. Intersection point M is the stream. Each of the following N lines contains three integers, Si, Ei, and Ci. Si and Ei (1 <= Si, Ei <= M) designate the intersections between which this ditch flows. Water will flow
through this ditch from Si to Ei. Ci (0 <= Ci <= 10,000,000) is the maximum rate at which water will flow through the ditch.
Output
Sample Input
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
Sample Output
50
#include"stdio.h"
#include"string.h"
#include"queue"
#include"stack"
#include"iostream"
#include"stdlib.h"
#define inf 99999999
#define M 50000
using namespace std;
struct st
{
int u,v,w,next;
}edge[M];
int t,head[M],cur[M],q[M],gap[M],dis[M];
void init()
{
t=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].next=head[u];
head[u]=t++; edge[t].u=v;
edge[t].v=u;
edge[t].w=0;
edge[t].next=head[v];
head[v]=t++;
}
void bfs(int start,int endl)//建立到汇点的距离层次图存在dis[]数组中
{
int rear=0,i,j;
memset(dis,-1,sizeof(dis));
memset(gap,0,sizeof(gap));//gap[x]记录dis[i]=x出现了多少次
dis[endl]=0;
gap[dis[endl]]=1;
q[rear++]=endl;
for(i=0;i<rear;i++)
{
for(j=head[q[i]];j!=-1;j=edge[j].next)
{
int v=edge[j].v;
if(dis[v]==-1)
{
++gap[dis[v]=dis[q[i]]+1];
q[rear++]=v;
}
}
}
}
int SAP(int start,int endl,int n)
{
int ans=0;
bfs(start,endl);
int cur[M];//代替head数组
memcpy(cur,head,sizeof(head));
int stack[M],top=0;//建立手工栈
int u=start,i;
while(dis[start]<n)
{
if(u==endl)//当搜到终点时即找到从原点到汇点的增光路,正常处理即可
{
int mini=inf,tep;
for(i=0;i<top;i++)
{
if(mini>edge[stack[i]].w)
{
mini=edge[stack[i]].w;
tep=i;
}
}
for(i=0;i<top;i++)
{
edge[stack[i]].w-=mini;
edge[stack[i]^1].w+=mini;
}
ans+=mini;
top=tep;
u=edge[stack[top]].u;//此时的u为变容量为0的u
}
if(dis[u]&&gap[dis[u]-1]==0)//出现了断层,没有增广路
break;
for(i=cur[u];i!=-1;i=edge[i].next)//遍历与u相连的未遍历的节点
{
int v=edge[i].v;
if(dis[v]!=-1)
{
if(edge[i].w&&dis[u]==dis[v]+1)//层次关系找到允许路径
break;
}
}
if(i!=-1)//找到允许弧
{
cur[u]=i;
stack[top++]=i;
u=edge[i].v;
}
else//无允许的路径,修改标号 当前点的标号比与之相连的点中最小的多1
{
int mini=n;
for(i=head[u];i!=-1;i=edge[i].next)
{
if(edge[i].w==0)continue;
int v=edge[i].v;
if(mini>dis[v])//找到与u相连的v中dep[v]最小的点
{
mini=dis[v];
cur[u]=i;//最小标号就是最新的允许弧
}
}
--gap[dis[u]];//dep[u] 的个数变化了 所以修改gap
++gap[dis[u]=mini+1];//将dep[u]设为min(dep[v]) + 1, 同时修改相应的gap[]
if(u!=start)//该点非源点&&以u开始的允许弧不存在,退点
u=edge[stack[--top]].u;
}
}
return ans;
}
int main()
{
int n,m;
while(scanf("%d%d",&m,&n)!=-1)
{
init();
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
int ans=SAP(1,n,n);
printf("%d\n",ans);
}
}
网络流SAP+gap+弧优化算法的更多相关文章
- poj 3469 最小割模板sap+gap+弧优化
/*以核心1为源点,以核心2为汇点建图,跑一遍最大流*/ #include<stdio.h> #include<string.h> #include<queue> ...
- 网络流 - dinic + 当前弧优化【代码】
这是初学网络流的时候从<算法竞赛进阶指南>抄下来的一份代码,自己理解的也不是很透彻. 注意,边要从 \(1\) 开始计,不然直接 \(xor\) 运算的话取反边会直接炸掉. #includ ...
- ARC085E(最小割规划【最大流】,Dinic当前弧优化)
#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll inf=0x3f3f3f3f;int cn ...
- 【最大流之Dinic算法】POJ1273 【 & 当前弧优化 & 】
总评一句:Dinic算法的基本思想比较好理解,就是它的当前弧优化的思想,网上的资料也不多,所以对于当前弧的优化,我还是费了很大的功夫的,现在也一知半解,索性就写一篇博客,来发现自己哪里的算法思想还没理 ...
- DINIC网络流+当前弧优化
DINIC网络流+当前弧优化 const inf=; type rec=record s,e,w,next:longint; end; var b,bb,d,q,tb:..] of longint; ...
- P3376 网络流-最大流模板题(Dinic+当前弧优化)
(点击此处查看原题) Dinic算法 Dinic算法相对于EK算法,主要区别在于Dinic算法对图实现了分层,使得我们可以用一次bfs,一次dfs使得多条增广路得到增广 普通的Dinic算法已经可以处 ...
- 解题报告:hdu 3572 Task Schedule(当前弧优化Dinic算法)
Problem Description Our geometry princess XMM has stoped her study in computational geometry to conc ...
- [Poj2112][USACO2003 US OPEN] Optimal Milking [网络流,最大流][Dinic+当前弧优化]
题意:有K个挤奶机编号1~K,有C只奶牛编号(K+1)~(C+K),每个挤奶机之多能挤M头牛,现在让奶牛走到挤奶机处,求奶牛所走的最长的一条边至少是多少. 题解:从起点向挤奶机连边,容量为M,从挤奶机 ...
- 网络流--最大流--Dinic模板矩阵版(当前弧优化+非当前弧优化)
//非当前弧优化版 #include <iostream> #include <cstdio> #include <math.h> #include <cst ...
随机推荐
- A/libc:fatal signal 11(SIGSEGV).code 1, fault addr 0x0 in tid 26488 (VideoEncoder)
在调试Camera模块:发现相同的代码在厂家提供的环境里边编译.就是ok的,在我们的源码树中编译,将HAL库推进去后.就会signal 11退出. 一.现象 F/libc ( ): Fatal sig ...
- r 数据分组处理
一.R语言实现数据的分组求和 实验数据集 姓名,年龄,班级 ,成绩, 科目 student <- data.frame ( name = c("s1", "s2&q ...
- 关于Java获取文件路径的几种方法
第一种:File f = new File(this.getClass().getResource("/").getPath()); System.out.println(f); ...
- Mastering the game of Go with deep neural networks and tree search浅析
Silver, David, et al. "Mastering the game of Go with deep neural networks and tree search." ...
- 【转】MFC 迅雷七窗体特效,使用DWM实现Aero Glass效果
从Windows Vista开始,Aero Glass效果被应用在了Home Premium以上的系统中(Home Basic不具有该效果).这种效果是由DWM(Desktop Window Mana ...
- Linux ad7606 驱动
Linux中已经移植好了ad7606,位于driver/staging/iio/adc/目录中.只要在板级文件中添加device中即可. 移植参考文档: https://wiki.analog.com ...
- e663. 在gif图像中获取透明和色彩的数量
A IndexColorModel is used to represent the color table of a GIF image. // Get GIF image Image image ...
- The configuration file 'appsettings.json' was not found and is not optional
问: .Net Core: Application startup exception: System.IO.FileNotFoundException: The configuration file ...
- Z字形扫描矩阵
问题描述 在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zigzag Scan).给定一个n×n的矩阵,Z字形扫描的过程如下图所示: 对于下面的4×4的矩阵, 1 5 3 9 3 7 5 ...
- Ant多渠道批量打包
由于我现在已经用更好的gradle了,所以关于ant我只是简单的讲一讲,如果想学gradle请到我的博客中查看 http://www.cnblogs.com/uncle2000 ant的配置请自行百度 ...