欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解

传送门 - POJ

传送门 - CodeVS

题意概括

给出一个图,告诉你边和容量,起点是1,汇点是n,让你求最大流。

题解

  最大流模板题。

  SAP跑一发!

  学习网络流

代码

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=+,M=N*;
int n,m;
struct edge{
int x,y,cap,flow,nxt;
// x,y 边的两个节点, cap 容量, flow 流量, nxt 指向 x 的下一条边
};
struct gragh{
int cnt,fst[N],dist[N],s,t,num[N],cur[N],p[N];
int q[N],head,tail;
edge e[M];
void set(int S,int T){//初始化
s=S,t=T,cnt=;
memset(fst,,sizeof fst);
memset(e,,sizeof e);
}
void add(int a,int b,int c){
// 建立正向边,容量为c
cnt++;
e[cnt].x=a,e[cnt].y=b,e[cnt].cap=c,e[cnt].flow=;
e[cnt].nxt=fst[a],fst[a]=cnt;
// 建立反向边,容量为0
cnt++;
e[cnt].x=b,e[cnt].y=a,e[cnt].cap=,e[cnt].flow=;
e[cnt].nxt=fst[b],fst[b]=cnt;
}
void re_bfs(){
memset(dist,-,sizeof dist);
memset(q,,sizeof q);
head=tail=dist[t]=;
q[++tail]=t;
while (head<tail)
for (int x=q[++head],i=fst[x];i;i=e[i].nxt){
int y=e[i].y;
if (e[i].cap==&&dist[y]==-)
q[++tail]=y,dist[y]=dist[x]+;
}
//bfs给所有的节点分层,得到每个点到达汇点的一种路径的边数
//据说可以达到常数级优化的效果
for (int i=;i<=n;i++)
if (dist[i]==-)
dist[i]=n;
}
int Augment(int &point){
int ex_Flow=<<;
for (int i=t;i!=s;i=e[p[i]].x)
if (e[p[i]].cap-e[p[i]].flow<ex_Flow)
ex_Flow=e[p[i]].cap-e[p[i]].flow,point=e[p[i]].x;
for (int i=t;i!=s;i=e[p[i]].x){
e[p[i]].flow+=ex_Flow;
e[p[i]^].flow-=ex_Flow;
}
return ex_Flow;
}
int ISAP(){
int x,y,MaxFlow=;
memset(num,,sizeof num);
for (int i=;i<=n;i++)
cur[i]=fst[i];//保存每个节点增广到的弧,
//作为当前弧优化的重要部分
for (int i=;i<=n;i++)
num[dist[i]]++;//算出每一个层次当前的节点数量
x=s;
while (dist[s]<n){
if (x==t){
MaxFlow+=Augment(x);
continue;
}
bool found=;
for (int i=cur[x];i;i=e[i].nxt){
y=e[i].y;
if (dist[y]+==dist[x]&&e[i].cap>e[i].flow){
p[y]=cur[x]=i,x=y,found=;
break;
}//找到一条可能为增广路的路径
}
if (!found){
int d=n+;
for (int i=fst[x];i;i=e[i].nxt)
if (e[i].cap>e[i].flow)
y=e[i].y,d=min(d,dist[y]+);
if (!(--num[dist[x]]))
return MaxFlow;//传说中的GAP优化
num[dist[x]=d]++;
cur[x]=fst[x];
if (x!=s)
x=e[p[x]].x;
}
}
return MaxFlow;
}
}g;
int main(){
while (~scanf("%d%d",&m,&n)){
g.set(,n);
for (int i=,a,b,c;i<=m;i++)
scanf("%d%d%d",&a,&b,&c),g.add(a,b,c);
g.re_bfs();
printf("%d\n",g.ISAP());
}
return ;
}

POJ1273 USACO 4.2.1 Drainage Ditches CodeVS1993草地排水 网络流 最大流 SAP的更多相关文章

  1. codevs1993 草地排水(最大流)

    1993 草地排水 USACO  时间限制: 2 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond   题目描述 Description 在农夫约翰的农场上,每逢下雨,Bes ...

  2. codevs1993草地排水(最大流)

    最近学了最大流,于是去codevs找了几道最大流裸题(这是我第一次写网络流). 题目大意:求一个图的最大流(就是这样的裸题) 第一次A网络流的题,发个博客纪念一下. var n,m,i,j,k,h,t ...

  3. USACO Section 4.2 Drainage Ditches(最大流)

    最大流问题.ISAP算法.注意可能会有重边,不过我用的数据结构支持重边.距离d我直接初始化为0,也可以用BFS逆向找一次. -------------------------------------- ...

  4. USACO Section 4.2: Drainage Ditches

    最大流的模板题 /* ID: yingzho1 LANG: C++ TASK: ditch */ #include <iostream> #include <fstream> ...

  5. Drainage Ditches - poj 1273(网络流模板)

    题意:1是源点,m是汇点,求出来最大流量,没什么好说的就是练习最大流的模板题 ************************************************************* ...

  6. POJ 1273 Drainage Ditches【图论,网络流】

    就是普通的网络流问题,想试试新学的dinic算法,这个算法暑假就开始看国家集训队论文了,之前一直都只用没效率的EK算法,真正学会这个算法还是开学后白书上的描述:dinic算法就是不断用BFS构建层次图 ...

  7. 【codevs1993】草地排水(最大流)

    最近学了最大流,于是去codevs找了几道最大流裸题(这是我第一次写网络流). 题目大意:求一个图的最大流(就是这样的裸题) 第一次A网络流的题,发个博客纪念一下. var n,m,i,j,k,h,t ...

  8. 【Codevs1993】草地排水(最大流,Dinic)

    题意:在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水 ...

  9. poj1273 Drainage Ditches Dinic最大流

    Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 76000   Accepted: 2953 ...

随机推荐

  1. .net常用的代码生成工具

    之前很多从事C#开发的用过动软代码生成器,然后随着IT技术的快速发展,涌现出很多优秀的工具关于.Net的,首推微软的Entity Framework,其次是NHibernate.Entity Fram ...

  2. ASP.NET MVC5高级编程 之 视图

    1.1理解视图约定 当创建一个项目模版时,可以注意到,项目以一种非常具体的方式包含了一个结构化的Views目录.在每一个控制器的View文件夹中,每一个操作方法都有一个同名的视图文件与其对应.这就提供 ...

  3. 51nod--1264 线段相交 (计算几何基础, 二维)

    题目: 1264 线段相交 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为 ...

  4. Light OJ 1009

    题意: 给你一个二分图, (可能不连通) 求可能多的子集元素个数: 思路: 直接DFS 给二分图染色就有了, 统计联通块中个数, 去最大值相加即可. #include<bits/stdc++.h ...

  5. 帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)

    作为一名前端工程师,必须搞懂JS中的prototype.__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞 ...

  6. winform里面打开网页(转)

    首先,新建一个winform项目,我在想,如果想要实现打开网页功能的话,应该会有一个控件什么之类的吧?查了工具栏,真的有一个名叫 WebBrowser的家伙,应该就是这货没错了.在网上查了它的资料更加 ...

  7. 在 Confluence 6 中禁用 workbox 应用通知

    如果你选择 不提供应用通知(does not provide in-app notifications): Confluence workbox 图标将不会可见同时用户也不能在这个服务器上访问 wor ...

  8. js中去除字符串中所有的html标签

    对于获取了一大堆字符串但是又不想要里面的html标签怎么办? 特别是像博客园这个富文本框中,可以带样式的,取出来的文章内容也是带样式的. 但是在某些地方只要显示文本不想显示其他标签,只好这样做. &l ...

  9. LeetCode(101):对称二叉树

    Easy! 题目描述: 给定一个二叉树,检查它是否是镜像对称的. 例如,二叉树 [1,2,2,3,4,4,3] 是对称的. 1 / \ 2 2 / \ / \ 3 4 4 3 但是下面这个 [1,2, ...

  10. 如何在EXCEL中找出第一列中不包含的第二列数据

    1.找出第一列中不包含的第二列数据:=IFERROR(VLOOKUP(A:A,B:B,1,0),"无") 2.A列相同,B列相加:=SUMIF(G:G,G1,J:J)