Some of the topics of network flow

Slowly more ...

template

The maximum flow


 

The maximum flow problem on the template HihoCoder: network flow two-maximum flow minimum cut theorem

Code on a copy of "Challenge Programming Contest"

#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;

const int MAX=10005;
const int INF=1<<30;

struct edge
{
    int to,cap,rev;
    edge(int x,int y,int z)
    {
        to=x,cap=y,rev=z;
    }
};

int s,t;
vector<edge> v[MAX];

inline void add_edge(int x,int y,int cap)
{
    v[x].push_back(edge(y,cap,v[y].size()));
    v[y].push_back(edge(x,0,v[x].size()-1));
}

int level[MAX];
queue<int> Q;

inline void bfs()
{
    memset(level,-1,sizeof(level));
    level[s]=0;
    Q.push(s);
    
    while(!Q.empty())
    {
        int x=Q.front();
        Q.pop();
        
        for(int i=0;i<v[x].size();i++)
        {
            edge &e=v[x][i];
            if(e.cap>0 && level[e.to]<0)
            {
                level[e.to]=level[x]+1;
                Q.push(e.to);
            }
        }
    }
}

int trip [MAX];

inline int dfs(int x,int f)
{
    if(x==t)
        return f;
    for(int &i=iter[x];i<v[x].size();i++)
    {
        edge &e=v[x][i];
        if(e.cap>0 && level[e.to]>level[x])
        {
            int d=dfs(e.to,min(f,e.cap));
            if(d>0)
            {
                e.cap - = d;
                v [e.to] [e.rev] .cap + = d;
                return d;
            }
        }
    }
    return 0;
}

inline int max_flow()
{
    int flow=0;
    while(1)
    {
        bfs();
        if(level[t]<0)
            break;
        
        memset(iter,0,sizeof(iter));
        
        int f=0;
        while((f=dfs(s,INF))>0)
            flow+=f;
    }
    return flow;
}

int n,m;

int main ()
{
//    freopen("input.txt","r",stdin);
    scanf("%d%d",&n,&m);
    s=1,t=n;
    
    for(int i=1;i<=m;i++)
    {
        int x, y, no;
        scanf("%d%d%d",&x,&y,&cap);
        add_edge(x,y,cap);
    }
    
    printf("%d ",max_flow());
    
    vector<int> cut;
    for(int i=1;i<=n;i++)
        if(level[i]>=0)
            cut.push_back(i);
    
    printf("%d\n",(int)cut.size());
    for(int i=0;i<cut.size();i++)
        printf("%d ",cut[i]);
    return 0;
}
View Code

 

A very bare maximum flow: CF 456E  ($ Soldier $ $ $ $ and Traveling $)

The $ a_i $, $ b_i $ as two sets of points ($ 1 $ ~ $ n $, $ n + 1 $ ~ $ 2n $), self sink source

Even the origin side, the second set of points in the first set is connected to the sink side, respectively, the flow restriction $ a_i $, $ b_i $

Even between the two sides of the first group to a second group, $ m $ paths can connect the sides $ $ 2M; since then staying, and can even out $ $ n-bar ($ I $ to $ n + i $). Traffic restrictions are limiting the outflow point

Output is each edge (if any) of traffic

Warm-up questions

#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;

const int N=205;
const int INF=1<<30;

struct edge
{
    int to,cap,rev;
    edge(int x,int y,int z)
    {
        to=x,cap=y,rev=z;
    }
};

int s,t;
vector<edge> v[N];

inline void add_edge(int x,int y,int cap)
{
    v[x].push_back(edge(y,cap,v[y].size()));
    v[y].push_back(edge(x,0,v[x].size()-1));
}

int level[N];
queue<int> Q;

inline void bfs()
{
    memset(level,-1,sizeof(level));
    level[s]=0;
    Q.push(s);
    
    while(!Q.empty())
    {
        int x=Q.front();
        Q.pop();
        
        for(int i=0;i<v[x].size();i++)
        {
            edge &e=v[x][i];
            if(e.cap>0 && level[e.to]<0)
            {
                level[e.to]=level[x]+1;
                Q.push(e.to);
            }
        }
    }
}

int path [n];

inline int dfs(int x,int f)
{
    if(x==t)
        return f;
    for(int &i=iter[x];i<v[x].size();i++)
    {
        edge &e=v[x][i];
        if(e.cap>0 && level[e.to]>level[x])
        {
            int d=dfs(e.to,min(f,e.cap));
            if(d>0)
            {
                e.cap - = d;
                v [e.to] [e.rev] .cap + = d;
                return d;
            }
        }
    }
    return 0;
}

inline int max_flow()
{
    int flow=0;
    while(1)
    {
        bfs();
        if(level[t]<0)
            break;
        
        memset(iter,0,sizeof(iter));
        
        int f=0;
        while((f=dfs(s,INF))>0)
            flow+=f;
    }
    return flow;
}

int n, m;
int a [N], b [N];
int years [N] [N];

int main ()
{
    scanf("%d%d",&n,&m);
    s=n*2+1,t=n*2+2;
    
    int suma=0,sumb=0;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),suma+=a[i];
    for(int i=1;i<=n;i++)
        scanf("%d",&b[i]),sumb+=b[i];
    
    if(suma!=sumb)
    {
        printf("NO\n");
        return 0;
    }
    
    for(int i=1;i<=n;i++)
        add_edge(s,i,a[i]);
    for(int i=1;i<=n;i++)
        add_edge(i,n+i,a[i]);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add_edge(x,n+y,a[x]);
        add_edge(y,n+x,a[y]);
    }
    for(int i=1;i<=n;i++)
        add_edge(n+i,t,b[i]);
    
    if(max_flow()!=sumb)
    {
        printf("NO\n");
        return 0;
    }
    
    printf("YES\n");
    for(int i=1;i<=n;i++)
        for(int j=0;j<v[i].size();j++)
        {
            int to=v[i][j].to;
            int flow=v[to][v[i][j].rev].cap;
            ans[i][to-n]=flow;
        }
    
    for(int i=1;i<=n;i++,printf("\n"))
        for(int j=1;j<=n;j++)
            printf("%d ",ans[i][j]);
    return 0;
}
View Code

 

(to be continued)

Guess you like

Origin www.cnblogs.com/LiuRunky/p/Network_Flow.html