Isap 的 CPP 模板

来源:互联网 发布:欧元 石油 知乎 编辑:程序博客网 时间:2024/05/06 04:43
 
#include <stdio.h>#include<iostream>#define N 110 #define oo 1000000000 using namespace std;int n, m, source, sink; int G[N][N]; int pi[N]; int CurrentNode[N]; int queue[N];int d[N];int numbs[N]; int rev_BFS() {    int i, j, head(0), tail(0);     for(i = 1; i <= n; i++)    numbs[d[i]=n] ++;     numbs[n]--;    d[sink] = 0;    numbs[0]++;     queue[ ++tail ] = sink;    while( head != tail )     {        i = queue[++head];            for(j = 1; j <= n; j++) {                 if(d[j]<n||G[j][i]==0)continue;                 queue[ ++tail ] = j;                     numbs[n]--;            d[j]=d[i]+1;            numbs[d[j]]++;         }    }    return 0;}int Augment() {    int i, j, tmp, width(oo);    for(i = sink, j = pi[i]; i != source; i = j, j = pi[j]) {        tmp = G[j][i];        if(tmp < width) width = tmp;    }    for(i = sink, j = pi[i]; i != source; i = j, j = pi[j]) {        G[j][i] -= width;        G[i][j] += width;    }    return width;}int Retreat(int &i) {    int tmp;    int j, mind(n-1);     for(j=1; j <= n; j++)      if(G[i][j] > 0 && d[j] < mind)        mind = d[j];    tmp = d[i];     numbs[d[i]]--;    d[i] = 1 + mind;    numbs[d[i]]++;        if( i != source ) i = pi[i];    return numbs[tmp];} int find_max_flow() {    int flow(0), i, j;    rev_BFS();    for(i=1; i<=n; i++) CurrentNode[i] = 1;      i = source;    for( ; d[source] < n ; )     {              for(j = CurrentNode[i]; j <= n; j++)             if( G[i][j] > 0 && d[i] == d[j] + 1 )             break;            if( j <= n ) {            CurrentNode[i] = j;            pi[j] = i;             i = j;                      if( i == sink ) {                flow += Augment();                i = source;             }        }              else {            CurrentNode[i] = 1;            if(Retreat(i)==0)                break;        }    }     return flow;} int main() {    int i,j,k,u,v,w,np,nc;     while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)    {        memset(G,0,sizeof(G));        for(i=1;i<=m;++i)        {            scanf(" (%d,%d)%d",&v,&u,&w);            G[v+1][u+1]+=w;        }         for(i=1;i<=np;++i)        {            scanf(" (%d)%d",&u,&w);            G[n+2][u+1]=w;        }        for(i=1;i<=nc;++i)        {            scanf(" (%d)%d",&v,&w);            G[v+1][n+1]=w;        }        source=n+2;sink=n+1;        n+=2;        printf("%d\n", find_max_flow());    }    return 0;}

邻接矩阵应该都会自己改吧,本题是POJ 1459 的,效果谁用谁知道。。。

应广大农民要求,写了一个邻接表版本的(未加rev_bfs),很简短:

#include <cstdio>#include <cstring>const int maxn = 201;const int maxm = 201;const int oo = ~0U >> 1;int cu[maxn],pi[maxn],head[maxn],num[maxn],d[maxn],g[maxm*2],e[maxm*2],next[maxm*2];int source,sink,n,m;int agument(){    int i,j,p,min = oo;    for (i = sink,j = pi[i]; i != source; i = j,j = pi[i])    {        p = cu[j];        if (g[p] < min) min = g[p];    }    for (i = sink,j = pi[i]; i != source; i = j,j = pi[i])    {        p = cu[j];        g[p] -= min;        g[p-1+(p&1)*2] += min;    }    return min;    }int retreat(int &x){        int mind = n-1,tmp,p;    for (p = head[x]; p > 0; p = next[p]) if (d[e[p]] < mind && g[p] > 0) mind = d[e[p]];    tmp = d[x];    --num[d[x]];    d[x] = mind+1;    ++num[d[x]];    if (x != source) x = pi[x];    return num[tmp];}int find_maxflow(){    int i,j,p,ans = 0;//    rev_bfs();    num[0] = n;    for (i = 1; i <= n; ++i) cu[i] = head[i];    i = source;    while (d[source] < n)    {        for (j = cu[i]; j != 0 ; j = next[j]) if (g[j] != 0 && d[i] == d[e[j]]+1) break;        if (j != 0)        {            cu[i] = j; j = e[j]; pi[j] = i; i = j;            if (i == sink)                                    {                ans += agument();                i = source;            }        }        else        {            cu[i] = head[i];            if (retreat(i) == 0) break;                                                       }                    }    return ans;        }int main(){    int i,j,k,l;//    freopen("1273.in","r",stdin);//    freopen("1273.out","w",stdout);     while (~scanf("%d%d",&m,&n))    {        memset(cu,0,sizeof(cu));        memset(pi,0,sizeof(pi));        memset(head,0,sizeof(head));        memset(num,0,sizeof(num));        memset(d,0,sizeof(d));        memset(g,0,sizeof(g));        memset(e,0,sizeof(e));        memset(next,0,sizeof(next));             for (i = 1; i <= m; ++i)        {            scanf("%d%d%d",&j,&k,&l);            e[i*2-1] = k;            e[i*2  ] = j;            next[i*2-1] = head[j];            next[i*2  ] = head[k];            head[j] = i*2-1;            head[k] = i*2  ;            g[i*2-1] = l;            g[i*2  ] = 0;                        }        source = 1;        sink = n;                printf("%d\n",find_maxflow());    }            return 0;}


原创粉丝点击