ネットワークフロー-EKアルゴリズム


EKアルゴリズムの構想:貪欲な思想に基づいて、毎回1本の起点から終点までの経路を選択して、言うまでもなく、この路の流量はこの経路の重み値が最小値であることに等しい.この道の重み値を流量を減らし、経路の反対側に流量を加え(欲張りに後悔する機会を与えることができる)、以上のステップを無限にループして、起点から終点までの道が見つからず、最後にすべての最小値を合わせると最大流になります.コード:
#include
#include
#include
#include
#define LL long long
#define Max 100005
const LL mod=1e9+7;
const LL LL_MAX=9223372036854775807;
using namespace std;
struct node
{
    int v,next;
    LL w;
}edge[Max];//       
int n,m;
int pre[Max],head[Max],rec[Max];//pre    ,rec            ,head      
LL flow[Max];//     
int no;
queueq;
void init()
{
   no=0;
   memset(head,-1,sizeof(head));
}
void add(int u,int v,LL c){
    edge[no].v=v,edge[no].w=c;
    edge[no].next=head[u],head[u]=no++;

    edge[no].v=u;edge[no].w=0;
    edge[no].next=head[v],head[v]=no++;
}

LL bfs(int st,int en)//  st-->en   
{
    memset(pre,-1,sizeof(pre));
    while(!q.empty())q.pop();
    pre[st]=st,flow[st]=INT_MAX;
    q.push(st);
    while(!q.empty()){
        int top=q.front();
        q.pop();
        int now=head[top];
        while(now!=-1){
            int t=edge[now].v;
            if(pre[t]==-1 && edge[now].w>0){//        ,     0
                flow[t]=min(flow[top],edge[now].w);
                pre[t]=top;
                rec[t]=now;
                q.push(t);
            }
            now=edge[now].next;
        }
        if(pre[en]!=-1)
            return flow[en];
    }
    return -1;
}
LL EK(int st,int en)
{
    LL ans=0;
    LL add;
    while((add=bfs(st,en))!=-1){//    st-->en   
        ans+=add;
        int k=en;
       // printf("%d
",add); while(k!=pre[k]){ edge[rec[k]].w-=add;// edge[rec[k]^1].w+=add;// // printf("%d
",k); k=pre[k]; } } return ans; } int main() { int x,y; LL c; while(scanf("%d%d",&m,&n)==2){ init(); for(int i=0;i