zoukankan      html  css  js  c++  java
  • AC日记——飞行员配对方案问题 洛谷 P2756

    题目背景

    第二次世界大战时期..

    题目描述

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

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

    输入输出格式

    输入格式:

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

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

    输出格式:

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

    输入输出样例

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

    思路:

      网络流24题之一;

      s到1~m连边,流量为1;

      t到m+1~m+n连边,流量为1;

      跑最大流;

      输出答案;

      然后根据边的流量输出配对方案;

    来,上代码:

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define maxn 205
    #define INF 0x7ffffff
    
    using namespace std;
    
    struct PrintType {
        int first,second;
    };
    struct PrintType ans[maxn];
    
    struct EdgeType {
        int to,next,flow;
    };
    struct EdgeType edge[maxn*100];
    
    int if_z,head[maxn],s,t=maxn-1,deep[maxn],cnt=1,m,n;
    
    char Cget;
    
    inline void in(int &now)
    {
        now=0,if_z=1,Cget=getchar();
        while(Cget>'9'||Cget<'0')
        {
            if(Cget=='-') if_z=-1;
            Cget=getchar();
        }
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
        now*=if_z;
    }
    
    inline void edge_add(int u,int v)
    {
        edge[++cnt].to=v,edge[cnt].flow=1,edge[cnt].next=head[u],head[u]=cnt;
        edge[++cnt].to=u,edge[cnt].flow=0,edge[cnt].next=head[v],head[v]=cnt;
    }
    
    bool BFS()
    {
        memset(deep,-1,sizeof(deep));
        queue<int>que;
        que.push(s),deep[s]=0;
        while(!que.empty())
        {
            int pos=que.front();
            for(int i=head[pos];i;i=edge[i].next)
            {
                if(deep[edge[i].to]<0&&edge[i].flow>0)
                {
                    deep[edge[i].to]=deep[pos]+1;
                    if(edge[i].to==t) return true;
                    que.push(edge[i].to);
                }
            }
            que.pop();
        }
        return false;
    }
    
    int flowing(int now,int flow)
    {
        if(now==t||flow<=0) return flow;
        int oldflow=0;
        for(int i=head[now];i;i=edge[i].next)
        {
            if(edge[i].flow<=0||deep[edge[i].to]!=deep[now]+1) continue;
            int pos=flowing(edge[i].to,min(flow,edge[i].flow));
            flow-=pos;
            oldflow+=pos;
            edge[i].flow-=pos;
            edge[i^1].flow+=pos;
            if(flow==0) return oldflow;
        }
        return oldflow;
    }
    
    bool cmp(struct PrintType a,struct PrintType b)
    {
        return a.first<b.first;
    }
    
    void dinic()
    {
        int pos=0;
        while(BFS()) pos+=flowing(s,INF);
        if(pos==0)
        {
            printf("No Solution!
    ");
            return ;
        }
        printf("%d
    ",pos);
        BFS();
        cnt=0;
        for(int i=head[s];i;i=edge[i].next)
        {
            if(edge[i].flow==0)
            {
                for(int j=head[edge[i].to];j;j=edge[j].next)
                {
                    if(edge[j].flow==0)
                    {
                        ans[++cnt].first=edge[i].to;
                        ans[cnt].second=edge[j].to;
                    }
                }
            }
        }
        sort(ans+1,ans+cnt+1,cmp);
        for(int i=1;i<=cnt;i++)
        {
            printf("%d %d
    ",ans[i].first,ans[i].second);
        }
    }
    
    int main()
    {
        in(m),in(n);
        int u,v;
        in(u),in(v);
        while(u!=-1&&v!=-1)
        {
            edge_add(u,v);
            in(u),in(v);
        }
        for(int i=1;i<=m;i++) edge_add(s,i);
        for(int i=1;i<=n;i++) edge_add(i+m,t);
        dinic();
        return 0;
    }
  • 相关阅读:
    python面试题解析(python基础篇80题)
    python面试题
    网络IO模型 主要 IO多路复用
    线程队列 线程池 协程
    线程的Thread模块 同步控制:锁,事件,信号量,条件,定时器
    进程池,线程的理论,Threading.Thread来创建线程
    进程之间的通信(IPC),对列,管道,数据共享.进程池初识
    Process 进程之间的数据隔离问题,守护进程,锁,信号量,事件
    js get the local domain and path fast
    github jekyll blog
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6435697.html
Copyright © 2011-2022 走看看