zoukankan      html  css  js  c++  java
  • 网络流模板

    最大流,ISAP

    抄的(http://www.cnblogs.com/wally/p/3274438.html)改了下。。

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    #define INF (1<<30)
    #define MAXN 111
    #define MAXM 2222
    
    struct Edge{
        int v,cap,flow,next;
    }edge[MAXM];
    int vs,vt,NE,NV;
    int head[MAXN];
    
    void addEdge(int u,int v,int cap){
        edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0;
        edge[NE].next=head[u]; head[u]=NE++;
        edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0;
        edge[NE].next=head[v]; head[v]=NE++;
    }
    
    int level[MAXN];
    int gap[MAXN];
    void bfs(){
        memset(level,-1,sizeof(level));
        memset(gap,0,sizeof(gap));
        level[vt]=0;
        gap[level[vt]]++;
        queue<int> que;
        que.push(vt);
        while(!que.empty()){
            int u=que.front(); que.pop();
            for(int i=head[u]; i!=-1; i=edge[i].next){
                int v=edge[i].v;
                if(level[v]!=-1) continue;
                level[v]=level[u]+1;
                gap[level[v]]++;
                que.push(v);
            }
        }
    }
    
    int pre[MAXN];
    int cur[MAXN];
    int ISAP(){
        bfs();
        memset(pre,-1,sizeof(pre));
        memcpy(cur,head,sizeof(head));
        int u=pre[vs]=vs,flow=0,aug=INF;
        gap[0]=NV;
        while(level[vs]<NV){
            bool flag=false;
            for(int &i=cur[u]; i!=-1; i=edge[i].next){
                int v=edge[i].v;
                if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){
                    flag=true;
                    pre[v]=u;
                    u=v;
                    //aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
                    aug=min(aug,edge[i].cap-edge[i].flow);
                    if(v==vt){
                        flow+=aug;
                        for(u=pre[v]; v!=vs; v=u,u=pre[u]){
                            edge[cur[u]].flow+=aug;
                            edge[cur[u]^1].flow-=aug;
                        }
                        //aug=-1;
                        aug=INF;
                    }
                    break;
                }
            }
            if(flag) continue;
            int minlevel=NV;
            for(int i=head[u]; i!=-1; i=edge[i].next){
                int v=edge[i].v;
                if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
                    minlevel=level[v];
                    cur[u]=i;
                }
            }
            if(--gap[level[u]]==0) break;
            level[u]=minlevel+1;
            gap[level[u]]++;
            u=pre[u];
        }
        return flow;
    }
    

    最小费用最大流

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    #define INF (1<<30)
    #define MAXN 111
    #define MAXM 2222
    struct Edge{
        int u,v,cap,cost,next;
    }edge[MAXM];
    int head[MAXN];
    int NV,NE,vs,vt;
    
    void addEdge(int u,int v,int cap,int cost){
        edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
        edge[NE].next=head[u]; head[u]=NE++;
        edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost;
        edge[NE].next=head[v]; head[v]=NE++;
    }
    bool vis[MAXN];
    int d[MAXN],pre[MAXN];
    bool SPFA(){
        for(int i=0;i<NV;++i){
            vis[i]=0;
            d[i]=INF;
        }
        vis[vs]=1;
        d[vs]=0;
        queue<int> que;
        que.push(vs);
        while(!que.empty()){
            int u=que.front(); que.pop();
            for(int i=head[u]; i!=-1; i=edge[i].next){
                int v=edge[i].v;
                if(edge[i].cap && d[v]>d[u]+edge[i].cost){
                    d[v]=d[u]+edge[i].cost;
                    pre[v]=i;
                    if(!vis[v]){
                        vis[v]=1;
                        que.push(v);
                    }
                }
            }
            vis[u]=0;
        }
        return d[vt]!=INF;
    }
    int MCMF(){
        int res=0;
        while(SPFA()){
            int flow=INF,cost=0;
            for(int u=vt; u!=vs; u=edge[pre[u]].u){
                flow=min(flow,edge[pre[u]].cap);
            }
            for(int u=vt; u!=vs; u=edge[pre[u]].u){
                edge[pre[u]].cap-=flow;
                edge[pre[u]^1].cap+=flow;
                cost+=flow*edge[pre[u]].cost;
            }
            res+=cost;
        }
        return res;
    }
    
  • 相关阅读:
    JAVA基础——编程练习(二)
    JAVA基础——面向对象三大特性:封装、继承、多态
    JVM内存
    50. Pow(x, n) (JAVA)
    47. Permutations II (JAVA)
    46. Permutations (JAVA)
    45. Jump Game II (JAVA)
    43. Multiply Strings (JAVA)
    42. Trapping Rain Water (JAVA)
    41. First Missing Positive (JAVA)
  • 原文地址:https://www.cnblogs.com/WABoss/p/4850748.html
Copyright © 2011-2022 走看看