题目描述:
有多组数据,每组数据中:
1为源点,n为汇点。
有 m条单向边,连接 u->v,其容量为c
求1到n的最大流
保证结果在int范围内 (Poj1273 Drainage Ditches)
模板:
//Dinic 模板
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=1e3+10;
const int maxe=1e3+10;
const int INF=0x7fffffff;
struct Edge
{
int from,to,cap,flow,next;
Edge() {}
Edge(int f,int t,int c,int fl,int n):from(f),to(t),cap(c),flow(fl),next(n) {}
}edges[maxe]; int pre[maxn],cnt;
int n,m;
int level[maxn]; //层次图
void init()
{
cnt=0; memset(pre,-1,sizeof(pre));
for (int i=1;i<=m;i++)
{
int u,v,cap;
scanf("%d%d%d",&u,&v,&cap);
edges[cnt]=Edge(u,v,cap,0,pre[u]); pre[u]=cnt++;
edges[cnt]=Edge(v,u,0,0,pre[v]); pre[v]=cnt++; //反向弧
}
}
int bfs(int s,int t) //建立层次图 类似SPFA
{
memset(level,0,sizeof(level));
level[s]=1; //起点在第一层
queue<int> q; q.push(s);
while (!q.empty())
{
int u=q.front(); q.pop();
if (u==t) return 1;
for (int i=pre[u];~i;i=edges[i].next)
{
int v=edges[i].to;
if (!level[v]&&edges[i].cap>edges[i].flow) //可改进
{
level[v]=level[u]+1;
q.push(v);
}
}
} return 0;
}
int dfs(int s,int maxf,int t) //寻找一条可行流 maxf为改进流量上限
{
if (s==t) return maxf; //到汇点
int ret=0;
for (int i=pre[s];~i;i=edges[i].next)
{
int v=edges[i].to;
if (level[v]==level[s]+1&&edges[i].cap>edges[i].flow) //可改进
{
int Min=min(maxf-ret,edges[i].cap-edges[i].flow); //可行流上最小的改进流量
int fl=dfs(v,Min,t);
edges[i].flow+=fl; //更新残量网络
edges[i^1].flow-=fl;
ret+=fl; //累加改进流量
if (ret==maxf) return ret;
}
}
return ret;
}
int dinic(int s,int t)
{
int ans=0;
while (bfs(s,t)) //无出现断层 可以建立层次图
ans+=dfs(s,INF,t); //寻找改进可行流
return ans; //输出最大流
}
void work()
{
printf("%d\n",dinic(1,n));
}
int main()
{
while (~scanf("%d%d",&m,&n))
{
init();
work();
}
return 0;
}
//EK 模板
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define E edges[i]
const int maxn=205;
const int INF=0x7FFFFFFF;
struct Edge
{
int from,to,cap,next,flow;
Edge() {}
Edge(int fr,int t,int ca,int flo,int nex):from(fr),to(t),cap(ca),flow(flo),next(nex) {}
}edges[500]; int cnt,pre[maxn];
int n,m,a[maxn],p[maxn];
//a[]记录改进流量
//p[]记录可行流路径
int maxflow(int s,int t) //求最大流
{
int flow=0;
for (;;)
{
memset(a,0,sizeof(a));
queue<int> q;
q.push(s); a[s]=INF;
while (!q.empty())
{
int now=q.front(); q.pop();
for (int i=pre[now];i!=-1;i=E.next)
{
if (!a[E.to]&&E.cap>E.flow)
{
p[E.to]=i;
a[E.to]=min(a[now],E.cap-E.flow);
q.push(E.to);
}
}
if (a[t]) break;
}
if (!a[t]) break;
for (int i=t;i!=s;i=edges[p[i]].from)
{
edges[p[i]].flow+=a[t]; //更新残量网络
edges[p[i]^1].flow-=a[t];
}
flow+=a[t];
}
return flow;
}
int main()
{
while (~scanf("%d%d",&n,&m))
{
cnt=0;
for (int i=1;i<=m;i++) pre[i]=-1;
for (int i=1;i<=n;i++)
{
int s,e,c;
scanf("%d%d%d",&s,&e,&c);
edges[cnt]=Edge(s,e,c,0,pre[s]); pre[s]=cnt; cnt++;
edges[cnt]=Edge(e,s,0,0,pre[e]); pre[e]=cnt; cnt++;
}
printf("%d\n",maxflow(1,m));
}
return 0;
}