Isap 的 CPP 模板

 
#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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章