您的位置:首页 > 理论基础 > 计算机网络

P3376 【模板】网络最大流dinic算法

2017-07-29 17:17 387 查看

 P3376 【模板】网络最大流

题目描述

如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。

输入输出格式

输入格式:

 

第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。

接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)

 

输出格式:

 

一行,包含一个正整数,即为该网络的最大流。

 

输入输出样例

输入样例#1:
4 5 4 3
4 2 30
4 3 20
2 3 20
2 1 30
1 3 40
输出样例#1:
50

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=10,M<=25

对于70%的数据:N<=200,M<=1000

对于100%的数据:N<=10000,M<=100000

样例说明:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int MAXN = 100100;
const int INF = 1e9;

struct Edge{
int to,c,nxt;
Edge(){}
Edge(int tt,int cc,int nn) {to = tt,c = cc,nxt = nn;}
}e[1000100];
queue<int>q;

int head[MAXN],dis[MAXN];
int s,t,n,m,tot = 1;

int read()
{
int x = 0, f = 1;char ch = getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f = -1; ch = getchar();}
while (ch>='0'&&ch<='9') {x = x*10+ch-'0'; ch = getchar();}
return x*f;
}
bool bfs()
{
q.push(s);
memset(dis,-1,sizeof(dis));
dis[s] = 0;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i=head[u]; i; i=e[i].nxt)
{
int v = e[i].to;
if (dis[v]==-1&&e[i].c>0)
{
dis[v] = dis[u]+1;
q.push(v);
}
}
}
if (dis[t]!=-1) return true;
return false;
}
int dfs(int u,int low)
{
if (u==t) return low;
int w,used = 0;
for (int i=head[u]; i; i=e[i].nxt)
{
int v = e[i].to;
if (dis[v]==dis[u]+1&&e[i].c>0)
{
w = dfs(v,min(low-used,e[i].c));
e[i].c -= w;
e[i^1].c += w;
used += w;
if (used==low) return low;
}
}
if (!used) dis[u] = -1;
return used;
}
int dinic()
{
int ans = 0,t;
while (bfs())
ans += dfs(s,INF);
return ans;
}
int main()
{
n = read();m = read();s = read();t = read();
for (int u,v,w,i=1; i<=m; ++i)
{
u = read();v = read();w = read();
e[++tot] = Edge(v,w,head[u]);
head[u] = tot;
e[++tot] = Edge(u,0,head[v]);
head[v] = tot;
}
printf("%d",dinic());
return 0;
}
很早以前的代码  

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: