#include <bits/stdc++.h>
#define N 40005
using namespace std;
int const inf = 0x3f3f3f3f;
int const MAX = 505;
struct Edge{
int u,v,c;
int next;
}edge[N];
int cnt;//边数
int head[N];
void addedge(int u,int v,int c)
{
//正向反向都要
edge[cnt].u=u; edge[cnt].v=v; edge[cnt].c=c;
edge[cnt].next=head[u]; head[u]=cnt++;
edge[cnt].u=v; edge[cnt].v=u; edge[cnt].c=0;
edge[cnt].next=head[v]; head[v]=cnt++;
}
int n, m;
int dep[MAX]; //分层
int source,sink; //源点,汇点
int bfs()//BFS对残余网络分层
{
queue<int> q;
while(!q.empty())
q.pop();
memset(dep, -1, sizeof(dep));
dep[source] = 0; //源点层数初始化为0
q.push(source);
while(!q.empty()){
int u = q.front();
q.pop();
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(edge[i].c> 0 && dep[v] == -1)
{
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[sink] != -1; //BFS分层是否能到达汇点
}
int dfs(int u, int delta)//DFS 寻找增广路,一次DFS可以寻找多条增广路
{
if(u == sink) //找到增广路
return delta;
int flow=0;
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(edge[i].c> 0 && dep[v] == dep[u] + 1){ //dfs从前一层向后一层寻找增广路
int tmp = dfs(v, min(delta-flow, edge[i].c));
// 路径上各边容量相应减少,反向边容量相应增加,总流量增加
edge[i].c -= tmp;
edge[i^1].c+= tmp;
flow+=tmp;
}
}
if(!flow) dep[u]=-1*inf;
return flow;
}
int dinic()
{
int ans = 0, tmp;
while(bfs()){
while(1){
tmp = dfs(1, inf);
if(tmp == 0)
break;
ans += tmp;
}
}
return ans;
}
int main()
{
while(~scanf("%d %d", &n, &m)){
cnt=0;
memset(head,-1,sizeof(head));
int u, v, c;
while(m--){
scanf("%d %d %d", &u, &v, &c);
addedge(u,v,c);
}
source=1,sink=n;
printf("%d\n", dinic());
}
return 0;
}
Dinic算法模板(自用)
最新推荐文章于 2022-05-18 23:58:12 发布