[POJ1273]草地排水 dinic模板

来源:互联网 发布:汽车加油软件 编辑:程序博客网 时间:2024/04/26 18:33

这题可以作为网络流模板看,这里贴一下自己的dinic模板

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int inf=0x3fffffff,N=400,M=500;int d[N],head[M],e[M],next[M],ver[M];int s,t,m,n,tot=1,maxflow=0;void add (int u,int v,int w) {    ver[++tot]=v;e[tot]=w;next[tot]=head[u];head[u]=tot;    ver[++tot]=u;e[tot]=0;next[tot]=head[v];head[v]=tot;//要在开头++tot与下面的tot初始化对应}bool bfs () {    queue<int> q;    memset(d,0,sizeof(d));    q.push(s); d[s]=1;    while (!q.empty()) {        int x=q.front(); q.pop();        for (int i=head[x];i;i=next[i])             if (e[i]&&!d[ver[i]]) {                q.push(ver[i]);                d[ver[i]]=d[x]+1;                if (ver[i]==t) return 1;            }    }    return 0;}int dinic (int x,int f) {    int rest=f;    if (x==t) return f;    for (int i=head[x];i&&rest;i=next[i])         if (e[i]&&d[ver[i]]==d[x]+1) {            int now=dinic(ver[i],min(e[i],rest));            if (!now) d[ver[i]]=0;//剪枝            e[i]-=now;            e[i^1]+=now;            rest-=now;        }    return f-rest;}int main () {    int u,v,w,tmp;    while (scanf("%d%d",&m,&n)!=EOF) {        s=1,t=n,tot=1,maxflow=0;//这里tot要初始化成1,与上面的++tot对应,这种存法忽略0,1两个存储单元,但能得到一些有意思的用处,见代码下面        memset(head,0,sizeof(head));        for (int i=1;i<=m;i++) {            scanf("%d%d%d",&u,&v,&w);            add(u,v,w);        }        while (bfs())             while (tmp=dinic(s,inf)) maxflow+=tmp;        printf("%d\n",maxflow);    }}

之前提到的有意思的性质:1、head数组可以初始化成0而不是-1,敲代码的时候感觉要舒服一些~
2、如果节点从1开始标号,那么对于结点i,2*i就代表指向这个结点的正向边。这个做法在 Codehunter 舞动的夜晚 有体现

0 0
原创粉丝点击