「网络流 24题」搭配飞行员
写在前面:
网络流是一种高深的算法,但是,我是一名小蒟蒻,因此,我还是慢慢来吧。。。
最近,我都会打算法题解,望大家支持。
题目大意:
飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员。由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多。因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行。
正解:
这是一道裸的网络流问题,我们可以让所有副驾驶员流向超级终点也就是
f
o
r
(
i
n
t
i
=
m
+
1
;
i
<
=
n
;
i
+
+
)
m
a
p
i
,
n
+
1
=
1
for(int\ i \ =\ m+1; i\ <=\ n;\ i++)\\ map_{i,n+1}=1
for(int i = m+1;i <= n; i++)mapi,n+1=1
反之,我们也可以让主驾驶员都源自超级源头
f
o
r
(
i
n
t
i
=
1
;
i
<
=
m
;
i
+
+
)
m
a
p
0
,
i
=
1
for(int\ i \ =\ 1; i\ <=\ m;\ i++)\\ map_{0,i}=1
for(int i = 1;i <= m; i++)map0,i=1
这样,我们就可以打一遍网络流,打dicnic的话你甚至可以把bfs去掉(因为没什么用)
来看看吧
code:
#include<bits/stdc++.h>
#define MAX 3*1e9
#define MIN -3*1e9
using namespace std;
int n,m,cnt,sum;
int dis[10001];
int mp[1001][1001];
int flag=1;
void dfs(int s,int minn)
{
dis[s]=1;
if(s==n+1)
{
flag=1;
cnt=minn;
sum+=minn;
return;
}
for(int i=0; i<=n+1; i++)
{
if(mp[s][i]&&!dis[i])
{
dfs(i,min(mp[s][i],minn));
if(flag)
{
mp[s][i]-=cnt;
mp[i][s]+=cnt;
return;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
int x,y;
for(int i=1; i<=m; i++) mp[0][i]=1;
while(~(scanf("%d%d",&x,&y))) mp[x][y]=1;
for(int i=m+1; i<=n; i++) mp[i][n+1]=1;
int o=300000000;
while(flag)
{
flag=0;
memset(dis,0,sizeof(dis));
dfs(0,o);
}
printf("%d",sum);
return 0;
}
写在最后:
接下来,请等我的新文章o!
敬请期待