LOJ6000搭配飞行员(网络流24题)

题目描述
飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员。由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多。

因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行。

输入格式
第一行,两个整数 n n n 与 m m m,表示共有 n n n 个飞行员,其中有 m m m 名飞行员是正驾驶员。
下面有若干行,每行有 2 2 2 个数字 a a a、b b b。表示正驾驶员 a a a 和副驾驶员 b b b 可以同机飞行。
注:正驾驶员的编号在前,即正驾驶员的编号小于副驾驶员的编号。

输出格式
仅一行一个整数,表示最大起飞的飞机数。

样例
样例输入
10 5
1 7
2 6
2 10
3 7
4 8
5 9
样例输出
4
数据范围与提示
2≤n≤100


很水的一道题,最大流跑二分图匹配

#include
using namespace std;
#define ll long long
ll ans; 
int n , m , S , T;
int linkk[110] , t;
int dep[110];
bool flag;
const ll oo = 1000000000000000000LL;
struct node{
    int n , y , v;
}e[100100];
int read()
{
    int sum = 0;char c = getchar();bool flag = true;
    while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
    while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
    if(flag)  return sum;
     else return -sum;
}  
void insert(int x,int y,int z)
{
    e[++t].y = y;e[t].n = linkk[x];e[t].v = z;linkk[x] = t;
    e[++t].y = x;e[t].n = linkk[y];e[t].v = 0;linkk[y] = t;
}
void init()
{
    t = 1;
    n = read();m = read();S = n + 1;T = n + 2;
    for(int i = 1;i <= m;++i) insert(S,i,1);
    for(int i = m + 1;i <= n;++i) insert(i,T,1);
    int a,b;
    while(scanf("%d",&a) != EOF)
    {
        b = read();
        insert(a,b,1);
    }
    return;
}
ll dfs(int x,ll lazy)
{
    if(x == T) return lazy;
    ll nowlazy = 0;
    ll d = 0;
    for(int i = linkk[x];i&&nowlazy < lazy;i = e[i].n)
    {
        int y = e[i].y;
        if(dep[y] == dep[x] + 1 && e[i].v > 0)
            if(d = dfs(y,min(1ll*e[i].v , lazy - nowlazy)))
            {
                nowlazy += d;
                e[i].v -= d;
                e[i^1].v += d; 
            }
    }
    if(nowlazy == 0) dep[x] = -1;
    return nowlazy;
}
queue<int>q;
bool bfs()
{
    memset(dep,-1,sizeof(dep));
    dep[S] = 0;q.push(S);
    while(q.size())
    {
        int v = q.front();
        for(int i = linkk[v];i;i = e[i].n)
            if(dep[e[i].y] == -1 && e[i].v > 0) 
                dep[e[i].y] = dep[v] + 1,q.push(e[i].y);
        q.pop();
    }
    if(dep[T] == -1) return false;
    return true;
}
int main()
{
    init();
    while(bfs())
    {       
        ll d;
        while(d = dfs(S,oo)) ans += d;
    }
    printf("%lld\n",ans);
    return 0;
} 

你可能感兴趣的:(网络流)