zoukankan      html  css  js  c++  java
  • 网络流24题-飞行员配对方案问题

    飞行员配对方案问题

    时空限制1000ms / 128MB

    题目背景

    第二次世界大战时期..

    题目描述

    英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。如何选择配对飞行的飞行员才能使一次派出最多的飞机。对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

    对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

    输入输出格式

    输入格式:

    第 1 行有 2 个正整数 m 和 n。n 是皇家空军的飞行员总数(n<100);m 是外籍飞行员数(m<=n)。外籍飞行员编号为 1~m;英国飞行员编号为 m+1~n。

    接下来每行有 2 个正整数 i 和 j,表示外籍飞行员 i 可以和英国飞行员 j 配合。最后以 2个-1 结束。

    输出格式:

    第 1 行是最佳飞行员配对方案一次能派出的最多的飞机数 M。接下来 M 行是最佳飞行员配对方案。每行有 2个正整数 i 和 j,表示在最佳飞行员配对方案中,飞行员 i 和飞行员 j 配对。如果所求的最佳飞行员配对方案不存在,则输出‘No Solution!’。

    输入输出样例

    输入样例:
    5 10
    1 7
    1 8
    2 6
    2 9
    2 10
    3 7
    3 8
    4 7
    4 8
    5 10
    -1 -1
    输出样例: 
    4
    1 7
    2 9
    3 8
    5 10 

    最大流。我选择了拆点,其实仔细想想发现拆不拆点都是一样的。
    还有一点需要特别特别注意的是判断两点之间是否有流,可以通过判断它的逆向边是否有流来实现。
    #include <bits/stdc++.h>
    using namespace std;
    const long long INF=LLONG_MAX/2;
    const int maxn=257;
    int now_edge=0,S,T;
    vector<int>edge[maxn];
    int dis[maxn],current[maxn];
    int fl[maxn][maxn]={0};
    
    struct ss
    {
        int v;
        long long flow;
    }edg[maxn*maxn];
    
    
    void addedge(int u,int v,long long flow)
    {
        fl[u][v]+=flow;
    
        edge[u].push_back(now_edge);
        edg[now_edge++]=(ss){v,flow};
        edge[v].push_back(now_edge);
        edg[now_edge++]=(ss){u,0};
    }
    
    bool bfs()
    {
        queue<int>q;
        q.push(S);
        memset(dis,0,sizeof(dis));
        dis[S]=1;
    
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
    
            int Size=edge[now].size();
    
            for(int i=0;i<Size;i++)
            {
                int to=edg[edge[now][i]].v;
                if(edg[edge[now][i]].flow>0&&dis[to]==0)
                {
                    dis[to]=dis[now]+1;
                    q.push(to);
                }
            }
        }
    
        if(dis[T]==0)return false;
        return true;
    }
    
    long long dfs(int now,long long maxflow)
    {
        if(now==T)return maxflow;
        int Size=edge[now].size();
    
        for(int i=current[now];i<Size;i++)
        {
            current[now]=i;
            ss &e=edg[edge[now][i]];
    
            if(dis[e.v]==dis[now]+1&&e.flow>0)
            {
                long long flow=dfs(e.v,min(maxflow,e.flow));
                if(flow!=0)
                {
                    fl[now][e.v]-=flow;
                    fl[e.v][now]+=flow;
                    e.flow-=flow;
                    edg[edge[now][i]^1].flow+=flow;
                    return flow;
                }
            }
        }
        return 0;
    }
    
    long long dinic()
    {
        long long ans=0;
        while(bfs())
        {
            long long flow;
            memset(current,0,sizeof(current));
            while(bool(flow=dfs(S,INF)))ans+=flow;
        }
        return ans;
    }
    
    int main()
    {
        int m,n,a,b;
         scanf("%d %d",&m,&n);
    
         while(scanf("%d %d",&a,&b)==2)
         {
             if(a==-1)break;
             addedge(a*2,b*2-1,1);
    
         }
    
         for(int i=1;i<=n;i++)addedge(2*i-1,2*i,1);
            S=2*n+1;
            T=2*n+2;
    
            for(int i=1;i<=m;i++)addedge(S,i*2-1,1);
            for(int i=m+1;i<=n;i++)addedge(i*2,T,1);
    
            long long ans=dinic();
            if(ans==0)printf("No Solution!
    ");
            else
            {
                printf("%lld
    ",ans);
                for(int i=1;i<=m;i++)
                for(int j=m+1;j<=n;j++)
                if(fl[j*2-1][i*2])
                {
                    printf("%d %d
    ",i,j);
                    break;
    
                }
            }
            return 0;
    }
    View Code
  • 相关阅读:
    NIO通道的学习笔记
    Struts学习笔记(启动过程)
    Struts2学习笔记(ResultType)
    11
    编写类String的构造函数、析构函数和赋值函数(转载)
    new与malloc的区别
    不用判断语句,求两个数中大的那个
    delete p和delete[] p的区别(转)
    (转)虚函数和纯虚函数区别
    不借助第三个变量交换两个整数的值
  • 原文地址:https://www.cnblogs.com/tian-luo/p/9507801.html
Copyright © 2011-2022 走看看