「网络流 24 题」搭配飞行员

#include<bits/stdc++.h>
using namespace std;

int m,n,tot=-1,h[1005],ans=0,tp=0;

struct node{
    int from,next,to,rest;
    int last;
}e[10005];

void add(int x,int y,int z){
    tot++;
    e[tot].next=h[x];
    h[x]=tot;
    e[tot].from=x;
    e[tot].to=y;
    e[tot].rest=z;
}

int dis[1005],g[1005],flow[1005];
bool vis[1005];

int bfs(int s,int t){
    queue<int>q;
    dis[s]=0;
    q.push(s);vis[s]=true;
    while(!q.empty()){
        int u=q.front();vis[u]=false;q.pop();
        for(int i=h[u];i!=(-1);i=e[i].next){
            if(dis[e[i].to]>dis[u]+1&&g[e[i].to]==(-1)&&e[i].rest>0){
                g[e[i].to]=i;
                flow[e[i].to]=min(flow[u],e[i].rest);
                dis[e[i].to]=dis[u]+1;
                if(vis[e[i].to]==false){
                    vis[e[i].to]=true;
                    q.push(e[i].to);
                }
            }
        }
    }
}

int EK(int s,int t){
    while(1){
        memset(dis,0x7f,sizeof(dis));
        memset(vis,false,sizeof(vis));
        memset(flow,0x7f,sizeof(flow));
        memset(g,-1,sizeof(g));
        bfs(s,t);
        if(g[t]==(-1))return 0;
        ans+=flow[t];
        for(int p=t;p!=(s);p=e[g[p]].from){
            e[g[p]].rest-=flow[t];
            e[g[p]].last=tp;
            e[g[p]^1].rest+=flow[t];
        }
    }
}

int main(){
    memset(h,-1,sizeof(h));
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        add(0,i,1);
        add(i,0,0);
    }
    for(int i=m+1;i<=n;i++){
        add(i,n+1,1);
        add(n+1,i,0);
    }int x,y;
    while(scanf("%d%d",&x,&y)!=EOF){
        add(x,y,1);
        add(y,x,0);
    }
    EK(0,n+1);
    if(ans==0){
        cout<<"No Solution!"<<endl;
        exit(0);
    }
    cout<<ans<<endl;
    
}
View Code

嘛,这个题就是网络流来做二分图最大匹配....

过水,有兴趣可以用匈牙利做做,或者重口味网络流哈哈

原文地址:https://www.cnblogs.com/shatianming/p/12227577.html