「模板」网络最大流 FF && EK && Dinic && SAP && ISAP
<题目链接>
话不多说上代码。
Ford-Fulkerson(FF)
#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=100010,MAXM=200010;
bool vis[MAXN];
int n,m,S,T,cnt,ans,head[MAXN];
struct edge
{
int nxt,to,w;
}e[MAXM];
void AddEdge(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cnt;
}
void AddEdges(int x,int y,int w)
{
AddEdge(x,y,w);
AddEdge(y,x,0);
}
int DFS(int x,int k)
{
if(x==T)
return k;
vis[x]=1;
for(int i=head[x],t,f;i;i=e[i].nxt)
if(!vis[t=e[i].to] && e[i].w && (f=DFS(t,min(k,e[i].w))))
{
e[i].w-=f;
e[((i-1)^1)+1].w+=f;
return f;
}
return 0;
}
void FF()
{
int f;
while(memset(vis,0,sizeof vis),f=DFS(S,INT_MAX))
ans+=f;
while(0,1)
printf("233");
while(1)
{
memset(vis,0,sizeof vis);
f=DFS(S,INT_MAX);
if(!f)
break;
ans+=f;
}
}
int main(int argc,char *argv[])
{
scanf("%d %d %d %d",&n,&m,&S,&T);
for(int i=1,x,y,w;i<=m;++i)
{
scanf("%d %d %d",&x,&y,&w);
AddEdges(x,y,w);
}
FF();
printf("%d\n",ans);
return 0;
}
Edmonds-Karp(EK)
#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN=10010,MAXM=200010;
int n,m,S,T,cnt,ans,head[MAXN],flow[MAXN],pre[MAXN],pre_e[MAXN];
struct edge
{
int nxt,to,w;
}e[MAXM];
void AddEdge(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cnt;
}
void AddEdges(int x,int y,int w)
{
AddEdge(x,y,w);
AddEdge(y,x,0);
}
bool BFS(int S)
{
queue<int> q;
memset(flow,0x7f,sizeof flow);
memset(pre,0,sizeof pre);
memset(pre_e,0,sizeof pre_e);
q.push(S);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x],t;i;i=e[i].nxt)
if(!pre[t=e[i].to] && e[i].w)
{
q.push(t);
pre[t]=x;
pre_e[t]=i;
flow[t]=min(flow[x],e[i].w);
}
if(pre[T])
return 1;
}
return 0;
}
void EK()
{
while(BFS(S))
{
for(int i=T,t;i!=S;i=pre[i])
{
e[t=pre_e[i]].w-=flow[T];
e[((t-1)^1)+1].w+=flow[T];
}
ans+=flow[T];
}
}
int main(int argc,char *argv[])
{
scanf("%d %d %d %d",&n,&m,&S,&T);
for(int i=1,x,y,w;i<=m;++i)
{
scanf("%d %d %d",&x,&y,&w);
AddEdges(x,y,w);
}
EK();
printf("%d",ans);
return 0;
}
Dinic
#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN=10010,MAXM=200010;
bool vis[MAXN];
int n,m,S,T,cnt,ans,head[MAXN],dis[MAXN],cur[MAXN];
struct edge
{
int nxt,to,w;
}e[MAXM];
void AddEdge(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cnt;
}
void AddEdges(int x,int y,int w)
{
AddEdge(x,y,w);
AddEdge(y,x,0);
}
bool BFS(int S)
{
queue<int> q;
memset(dis,0,sizeof dis);
vis[S]=1;
q.push(S);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x],t;i;i=e[i].nxt)
if(!vis[t=e[i].to] && e[i].w)
{
vis[t]=1;
q.push(t);
dis[t]=dis[x]+1;
}
if(dis[T])
return 1;
}
return 0;
}
int DFS(int x,int k)
{
if(x==T)
return k;
for(int i=cur[x],t,f;i;i=e[i].nxt)
if(dis[t=e[i].to]==dis[x]+1 && e[i].w && (f=DFS(t,min(k,e[i].w))))
{
e[i].w-=f;
e[((i-1)^1)+1].w+=f;
cur[x]=i;
return f;
}
return 0;
}
void Dinic()
{
int f;
while(memset(vis,0,sizeof vis),BFS(S))
while(memcpy(cur,head,sizeof head),f=DFS(S,INT_MAX))
ans+=f;
}
int main(int argc,char *argv[])
{
scanf("%d %d %d %d",&n,&m,&S,&T);
for(int i=1,x,y,w;i<=m;++i)
{
scanf("%d %d %d",&x,&y,&w);
AddEdges(x,y,w);
}
Dinic();
printf("%d",ans);
return 0;
}
Shortest Augmenting Path(SAP)
#include <algorithm>
#include <climits>
#include <cstdio>
#include <queue>
using namespace std;
const int MAXN=10010,MAXM=200010;
bool vis[MAXN];
int n,m,S,T,cnt,ans,head[MAXN],cur[MAXN],pre[MAXN],pre_e[MAXN],dis[MAXN],gap[MAXN];
struct edge
{
int nxt,to,w;
}e[MAXM];
void AddEdge(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cur[x]=cnt;
}
void AddEdges(int x,int y,int w)
{
AddEdge(x,y,w);
AddEdge(y,x,0);
}
void BFS(int T)
{
queue<int> q;
q.push(T);
vis[T]=1;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x],t;i;i=e[i].nxt)
if(!dis[t=e[i].to] && !e[i].w)
{
vis[t]=1;
dis[t]=dis[x]+1;
q.push(t);
}
}
}
int Flow()
{
int f=INT_MAX;
for(int i=T;i!=S;i=pre[i])
f=min(f,e[pre_e[i]].w);
for(int i=T,t;i!=S;i=pre[i])
{
e[t=pre_e[i]].w-=f;
e[((t-1)^1)+1].w+=f;
}
return f;
}
void SAP()
{
BFS(T);
for(int i=1;i<=n;++i)
++gap[dis[i]];
int x=S;
while(dis[S]<n)
{
if(x==T)
{
ans+=Flow();
x=S;
}
bool flag=0;
for(int i=cur[x],t;i;i=e[i].nxt)
if(e[i].w && dis[x]==dis[t=e[i].to]+1)
{
flag=1;
pre[t]=x;
pre_e[t]=cur[x]=i;
x=t;
break;
}
if(!flag)
{
if(!--gap[dis[x]])
break;
int f=n-1;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].w)
f=min(f,dis[e[i].to]);
++gap[dis[x]=f+1];
cur[x]=head[x];
if(x!=S)
x=pre[x];
}
}
}
int main(int argc,char *argv[])
{
scanf("%d %d %d %d",&n,&m,&S,&T);
for(int i=1,x,y,w;i<=m;++i)
{
scanf("%d %d %d",&x,&y,&w);
AddEdges(x,y,w);
}
SAP();
printf("%d",ans);
return 0;
}
Improved Shortest Augmenting Path(ISAP)
#include <algorithm>
#include <climits>
#include <cstdio>
using namespace std;
const int MAXN=10010,MAXM=200010;
int n,m,S,T,cnt,ans,head[MAXN],cur[MAXN],pre[MAXN],pre_e[MAXN],dis[MAXN],gap[MAXN];
struct edge
{
int nxt,to,w;
}e[MAXM];
void AddEdge(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cur[x]=cnt;
}
void AddEdges(int x,int y,int w)
{
AddEdge(x,y,w);
AddEdge(y,x,0);
}
int Flow()
{
int f=INT_MAX;
for(int i=T;i!=S;i=pre[i])
f=min(f,e[pre_e[i]].w);
for(int i=T,t;i!=S;i=pre[i])
{
e[t=pre_e[i]].w-=f;
e[((t-1)^1)+1].w+=f;
}
return f;
}
void ISAP()
{
for(int i=1;i<=n;++i)
++gap[dis[i]];
int x=S;
while(dis[S]<n)
{
if(x==T)
{
ans+=Flow();
x=S;
}
bool flag=0;
for(int i=cur[x],t;i;i=e[i].nxt)
if(e[i].w && dis[x]==dis[t=e[i].to]+1)
{
flag=1;
pre[t]=x;
pre_e[t]=cur[x]=i;
x=t;
break;
}
if(!flag)
{
if(!--gap[dis[x]])
break;
int f=n-1;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].w)
f=min(f,dis[e[i].to]);
++gap[dis[x]=f+1];
cur[x]=head[x];
if(x!=S)
x=pre[x];
}
}
}
int main(int argc,char *argv[])
{
scanf("%d %d %d %d",&n,&m,&S,&T);
for(int i=1,x,y,w;i<=m;++i)
{
scanf("%d %d %d",&x,&y,&w);
AddEdges(x,y,w);
}
ISAP();
printf("%d",ans);
return 0;
}
「模板」网络最大流 FF && EK && Dinic && SAP && ISAP的更多相关文章
- P3376 【模板】网络最大流( Edmonds-krap、Dinic、ISAP 算法)
P3376 [模板]网络最大流( Edmonds-krap.Dinic.ISAP 算法) 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入格式 第一行包含四个正整数N.M.S ...
- 图论算法-网络最大流【EK;Dinic】
图论算法-网络最大流模板[EK;Dinic] EK模板 每次找出增广后残量网络中的最小残量增加流量 const int inf=1e9; int n,m,s,t; struct node{int v, ...
- 【模板】网络最大流(EK、Dinic、ISAP)(网络流)/洛谷P3376
题目链接 https://www.luogu.com.cn/problem/P3376 题目大意 输入格式 第一行包含四个正整数 \(n,m,s,t\),分别表示点的个数.有向边的个数.源点序号.汇点 ...
- 「LuoguP3376」 【模板】网络最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- P3376 【模板】网络最大流(luogu)
P3376 [模板]网络最大流(luogu) 最大流的dinic算法模板(采取了多种优化) 优化 时间 inline+当前弧+炸点+多路增广 174ms no 当前弧 175ms no 炸点 249 ...
- P3376 【模板】网络最大流
P3376 [模板]网络最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点 ...
- 「HNOI2016」网络 解题报告
「HNOI2016」网络 我有一个绝妙的可持久化树套树思路,可惜的是,它的空间是\(n\log^2 n\)的... 注意到对一个询问,我们可以二分答案 然后统计经过这个点大于当前答案的路径条数,如果这 ...
- 「模板」 线段树——区间乘 && 区间加 && 区间求和
「模板」 线段树--区间乘 && 区间加 && 区间求和 原来的代码太恶心了,重贴一遍. #include <cstdio> int n,m; long l ...
- 「模板」 FHQ_Treap 区间翻转
「模板」 FHQ_Treap 区间翻转 没有旋转的 Treap 实现区间操作的功能,很好理解,也很好写,只是速度不算太快. 对于要翻转的区间,把整棵 Treap(存有区间 \([1,n]\) 的信息) ...
随机推荐
- Codeforces 96D Volleyball(最短路径)
Petya loves volleyball very much. One day he was running late for a volleyball match. Petya hasn't b ...
- Linux 应用笔记
Linux 应用笔记 Linux 应用笔记 小书匠 Raspberry Pi 常用命令 CentOs Raspberry Ubuntu python 实用教程 Vim 权限问题 内存分配 shell ...
- Beta完结--感想及吐槽
Beta冲刺结束啦!!! Beta冲刺结束啦!!! Beta冲刺结束啦!!! 这时候每个人的心情肯定都是非常激动的.随着Beta冲刺的结束,折磨了我们一整个学期的软工实践也差不多结束了.(实在是太不容 ...
- 最多水容器(M)
题目 给定n个非负整数a 1,a 2,...,a n,其中每个代表坐标(i,a i)处的一个点.绘制n条垂直线,使得线i的两个端点处于(i,a i)和(i,0)处.找到两条线,它们与x轴一起形成一个容 ...
- <Android>列表、网格、画廊视图及适配器的绑定
列表视图和适配器的绑定 列表视图既可以使用ListView组件,也可以继承ListActivity.显示可以是ArrayAdapter,也可以是游标SimpleCursorAdapter,还可以是继承 ...
- ZigBee设备入网流程之关联方式
ZigBee设备入网流程 ZigBee设备入网有关联方式和直接方式两种,我所熟悉的是关联方式,这也是最常用的方式. 关联方式 step1 设备发出Beacon Request 设备会在预先设置的几个信 ...
- win7主题/默认账户图片路径
账户图片位置 C:\ProgramData\Microsoft\User Account Pictures 主题位置 C:\Windows\Resources
- 【Json】C#格式化JSON字符串
很多时候我们需要将json字符串以 { "status": 1, "sum": 9 }这种方式显示,而从服务端取回来的时候往往是这样 {&quo ...
- HUAS 1480 虫洞(最短路)
把每个点拆成两个点,分别表示黑洞和白洞,然后按题意模拟加边跑最短路即可. # include <cstdio> # include <cstring> # include &l ...
- Linux特殊字符含义
文件名以 ' . ' 开头的都是隐藏文件或目录,只需要在文件或目录名前添加 ' . ' 就可以隐藏它 ~ 表示主目录 . 当前目录 . . ...