题意:给出网络流的一些边,求节点1到节点n的最大流。
难度:0
题解:直接连边求最大流。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define forn(i,n) for(i=0;i<(n);i++)
#define for1(i,n) for(i=1;i<=(n);i++)
#define forh(i,u) for(i=head[u];i!=-1;i=edge[i].next)
#define inf (1<<29)
const int maxn = 222 , maxm = 555;
int n , m;
struct Edge {
int u,v,c,next;
}edge[maxm];
int E,head[maxn];
int dist[maxn];
int que[maxn];
int sta[maxn];
void init() {
E = 0; memset(head,-1,sizeof(head));
}
void _add(int u,int v,int c) {
edge[E].u=u;edge[E].v=v;edge[E].c=c;edge[E].next=head[u];head[u]=E++;
}
void addedge(int u,int v,int c) {
_add(u,v,c); _add(v,u,0);
}
int dinic(int s,int t) {
int ans = 0;
while(true) {
int left,right,u,v,c,i;
memset(dist,-1,sizeof(dist));
left = right = 0;
que[right ++] = s;
dist[s] = 0;
while(left < right) {
u = que[left ++];
forh(i,u) {
u=edge[i].u;
v=edge[i].v;
c=edge[i].c;
if(c>0 && dist[v] == -1) {
dist[v] = dist[u] + 1;
que[right ++] = v;
if(v == t) {
left = right;
break;
}
}
}
}
if(dist[t] == -1) break;
int top = 0;
int now = s;
while(true) {
if(now != t) {
forh(i,now) {
u=edge[i].u;
v=edge[i].v;
c=edge[i].c;
if(c > 0 && dist[u] + 1 == dist[v])
break;
}
if(i != -1) {
sta[top ++] = i;
now = edge[i].v;
}
else {
if(top == 0) break;
dist[edge[sta[--top]].v] = -1;
now = edge[sta[top]].u;
}
}
else {
int flow = inf , ebreak;
forn(i,top)
if(flow > edge[sta[i]].c)
flow = edge[sta[ebreak = i]].c;
ans += flow;
forn(i,top) {
edge[sta[i]].c -= flow;
edge[sta[i]^1].c += flow;
}
now = edge[sta[top = ebreak]].u;
}
}
}
return ans;
}
int main() {
while(~scanf("%d%d",&m,&n)) {
init();
while(m--) {
int u , v , c;
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c);
}
int ans = dinic(1,n);
printf("%d\n",ans);
}
return 0;
}