ISAP模板

#include<bits/stdc++.h>  
//#pragma comment(linker, "/STACK:1024000000,1024000000")   
#include<stdio.h>  
#include<algorithm>  
#include<queue>  
#include<string.h>  
#include<iostream>  
#include<math.h>  
#include<set>  
#include<map>  
#include<vector>  
#include<iomanip>  
using namespace std;  
#define ll long long  
#define pb push_back  
#define FOR(a) for(int i=1;i<=a;i++)  
const int inf=0x3f3f3f3f;  
const int maxn=1e6+9;    
  
int num_nodes;  //预留超级源给0,所有的点是0到num_nodes-1
int tot;  
int d[maxn],cur[maxn],source,sink;  
int p[maxn],num[maxn],vis[maxn];  
  
struct EDGE{  
    int from,to,cap,flow;  
};  
vector<EDGE>edge;  
vector<int>G[maxn];  
  
void init(){  
    edge.clear();  
    for(int i=0;i<maxn;i++)G[i].clear();  
}  
  
void addedge(int u,int v,int w){  
    edge.push_back((EDGE){u,v,w,0});  
    edge.push_back((EDGE){v,u,0,0});  
    tot=edge.size();  
    G[u].push_back(tot-2);  
    G[v].push_back(tot-1);  
}  
  
int bfs(){      //只跑一次初始化原图层次,void也行
    memset(vis,0,sizeof vis);  
    queue<int>Q;  
    Q.push(sink);  
    vis[sink]=1;  
    d[sink]=0;  
    while(!Q.empty()){  
        int u=Q.front();  
        Q.pop();  
        int sz=G[u].size();  
        for(int i=0;i<sz;++i){  
            EDGE &e=edge[G[u][i]^1];  
            if(!vis[e.from] && e.cap>e.flow){  
                vis[e.from]=1;  
                d[e.from]=d[u]+1;  
                Q.push(e.from);  
            }  
        }  
    }  
    return vis[source];  
}  
  
int augment(){  //遍历处理出的路径
    int u=sink,a=inf;  
    while(u!=source){  
        EDGE &e=edge[p[u]];  
        a=min(a,e.cap-e.flow);  
        u=edge[p[u]].from;  
    }  
    u=sink;  
    while(u!=source){  
        edge[p[u]].flow+=a;  
        edge[p[u]^1].flow-=a;  
        u=edge[p[u]].from;  
    }  
    return a;  
}  
  
int maxflow(){  
    int flow=0;  
    bfs();             //处理出d数组表示层次图 
    memset(num,0,sizeof num);  
    for(int i=0;i<num_nodes;i++)num[d[i]]++;    //各个层次的点有多少个  
    int u=source;  
    memset(cur,0,sizeof cur);              //当前弧编号,前面不行后面也不会用
    while(d[source]<num_nodes){          //残量网络可达
        if(u==sink){                      //增广到终点
            flow+=augment();  
            u=source;  
        }  
        bool advance=false;  
        int sz=G[u].size();  
        for(int i=cur[u];i<sz;i++){  
            EDGE &e=edge[G[u][i]];  
            if(e.cap>e.flow && d[u]==d[e.to]+1){  
                advance=true;  
                p[e.to]=G[u][i];  
                cur[u]=i;  
                u=e.to;  
                break;  
            }  
        }  
        if(!advance){  
            int m=num_nodes-1;  
            int sz=G[u].size();  
            for(int i=0;i<sz;i++){  
                if(edge[G[u][i]].cap>edge[G[u][i]].flow){  
                    m=min(m,d[edge[G[u][i]].to]);  
                }             
            }  
            if(--num[d[u]]==0)break;  
            num[d[u]=m+1]++;  
            cur[u]=0;  
            if(u!=source)u=edge[p[u]].from;  
        }  
    }  
    return flow;  
}  

/******
main:
init(),num_nodes,source,sink
******/

posted @ 2017-07-04 18:16  Drenight  阅读(235)  评论(0编辑  收藏  举报