洛谷 P2756 飞行员配对方案问题

题目描述

二分图板子题,按读入建边即可。

注意m和n分别代表什么

(话说洛谷数据是真的水。。m*2=n的数据有82分。。我一开始就是这弄错了)

代码(二分图真的难敲,,这里是dinic )

#include<bits/stdc++.h>
using namespace std;
 
inline void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);x*=f;
}
 
inline void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar((x%10)^48);
}
inline void write(int x) {if(!x) putchar('0');else print(x);putchar('
');}
 
#define maxn 1000050

int n,m,s,t,max_flow,tot=1,k;
int head[maxn],dis[maxn],vis[maxn];
struct edge{int to,nxt,w;}e[maxn<<1];

void add(int u,int v,int w) {e[++tot]=(edge){v,head[u],w},head[u]=tot;}
void ins(int u,int v,int w) {add(u,v,w),add(v,u,0);}

int bfs() {
    memset(vis,0,sizeof vis);
    memset(dis,63,sizeof dis);//write(dis[0]);
    queue<int > q;q.push(s);vis[s]=1;dis[s]=0;
    while(!q.empty()) {
        int now=q.front();q.pop();vis[now]=0;
        for(int i=head[now];i;i=e[i].nxt)
            if(e[i].w>0&&dis[e[i].to]>dis[now]+1) {
                dis[e[i].to]=dis[now]+1;
                if(!vis[e[i].to]) vis[e[i].to]=1,q.push(e[i].to);
            }
    }return dis[t]<1e9;
}

int dfs(int u,int flow) {
    if(u==t) return flow;
    for(int i=head[u];i;i=e[i].nxt)
        if(e[i].w>0&&dis[e[i].to]==dis[u]+1) {
            int f=dfs(e[i].to,min(flow,e[i].w));
            if(f>0) {e[i].w-=f,e[i^1].w+=f;return f;}
        }
    dis[u]=-1;return 0;
}

int dinic() {
    max_flow=0;
    while(bfs()) {
        int flow;
        while((flow=dfs(s,1e9))) max_flow+=flow;
    }return max_flow;
}

int main() {
    read(m),read(n);s=0,t=n+1;
    int x,y;
    while(1) {
        read(x),read(y);if(x<0) break;
        ins(x,y,1);
    }
    for(int i=1;i<=m;i++) ins(s,i,1);
    for(int i=m+1;i<=n;i++) ins(i,t,1);
    dinic();write(max_flow);
    for(int i=1;i<=m;i++) {
        for(int j=head[i];j;j=e[j].nxt)
            if(e[j].to!=s&&(!(j&1))) if(!e[j].w) printf("%d %d
",i,e[j].to);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hbyer/p/9923181.html