网络流24题 飞行员配对方案问题
Posted aaddvvaanntteezz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流24题 飞行员配对方案问题相关的知识,希望对你有一定的参考价值。
题解
- 很裸的网络流,加入源点和汇点对二分图求最大匹配,跑最大流就行了
- 记录方案只需要看对应边的剩余容量是否为0。
查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1000+5;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
struct graph
{
int head[maxn],nxt[maxn<<1],to[maxn<<1],w[maxn<<1],sz;
void init(){memset(head,-1,sizeof(head));}
graph(){init();}
void push(int a,int b,int c){nxt[sz]=head[a],to[sz]=b,w[sz]=c,head[a]=sz++;}
int& operator[](const int a){return to[a];}
}g;
int s,t;
queue<int>q;
int d[maxn],now[maxn];
bool bfs()
{
memset(d,0,sizeof(d));
while(q.size())q.pop();
q.push(s);
d[s]=1,now[s]=g.head[s];
while(!q.empty()){
int p = q.front();
q.pop();
for(int i = g.head[p];~i;i = g.nxt[i]){
if(g.w[i]&&!d[g[i]]){
d[g[i]]=d[p]+1;
q.push(g[i]);
now[g[i]]=g.head[g[i]];
if(g[i]==t){
return true;
}
}
}
}
return false;
}
int dinic(int x,int flow)
{
if(x==t)return flow;
int rest = flow,i,k;
for(i = now[x];~i&&rest;i = g.nxt[i]){
if(g.w[i]&&d[g[i]]==d[x]+1){
k = dinic(g[i],min(g.w[i],rest));
if(!k)d[g[i]]=0;
g.w[i]-=k;
g.w[i^1]+=k;
rest-=k;
}
}
now[x]=i;
return flow-rest;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("simple.in", "r", stdin);
freopen("simple.out", "w", stdout);
#endif
int n,m;
scanf("%d%d",&m,&n);
int x,y;
s=0,t=n+1;
while(~scanf("%d%d",&x,&y)&&x!=-1){
g.push(x,y,1),g.push(y,x,0);
}
for(int i = 1;i <= m;++i){
g.push(s,i,1),g.push(i,s,0);
}
for(int i = m+1;i <= n;++i){
g.push(i,t,1),g.push(t,i,0);
}
int flow = 0,maxflow=0;
while(bfs()){
while(flow=dinic(s,inf))maxflow+=flow;
}
printf("%d
",maxflow);
for(int i = 1;i <= m;++i){
for(int j = g.head[i];~j;j = g.nxt[j]){
if(g.w[j]==0&&g[j]!=0){
printf("%d %d
",i,g[j]);
}
}
}
return 0;
}
以上是关于网络流24题 飞行员配对方案问题的主要内容,如果未能解决你的问题,请参考以下文章