• 洛谷 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 

    二分图 + 网络流 + 不过样例式AC
    屠龙宝刀点击就送
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #define inf 1e9
    
    using namespace std;
    
    struct node
    {
        int next,to,dis;
    }e[100*100];
    bool vis[1501];
    queue<int>q;
    int cur[1501],x[1501],num,deep[1501],Answer,S,T,head[100*100],tot=1,m,n;
    void add_edge(int u,int v,int l)
    {
        e[++tot].to=v;
        e[tot].next=head[u];
        e[tot].dis=l;
        head[u]=tot;
    }
    bool bfs(int s,int t)
    {
        memset(vis,0,sizeof(vis));
        memset(deep,0x7f,sizeof(deep));
        while(!q.empty() )
        q.pop() ;
        for(int i=0;i<=T;++i)
        cur[i]=head[i];
        q.push(s);deep[s]=0;vis[s]=1;
        while(!q.empty() )
        {
            int Top=q.front() ;
            q.pop() ;
            vis[Top]=false;
            for(int i=head[Top];i!=-1;i=e[i].next)
            {
                int to=e[i].to;
                if(deep[to]>inf&&e[i].dis)
                {
                    deep[to]=deep[Top]+1;
                    if(!vis[to]) {q.push(to);vis[to]=1;} 
                }
            }
        }
        return deep[t]<inf;
    }
    int dfs(int now,int t,int limit)
    {
        int i,f,rest=0;
        if(limit==0) return 0;
        if(now==t) return limit;
        for(i=head[now];i!=-1;i=e[i].next)
        {
            int To=e[i].to;
            if(deep[To]==deep[now]+1&&(f=dfs(To,t,min(e[i].dis,limit))))
            {
                if(f) x[now]=To;
                rest+=f;
                limit-=f;
                e[i].dis-=f;
                e[i^1].dis+=f;
                x[now]=To;
                if(!limit)
                break;
            }
        }
        return rest;
    }
    void dinic(int s,int t)
    {
        while(bfs(s,t))
            Answer+=dfs(s,t,inf);
    }
    int main()
    {
        scanf("%d%d",&m,&n);
        memset(head,-1,sizeof(head));
        S=0;T=n+1;
        for(int i=1;i<=m;++i) {add_edge(S,i,1);add_edge(i,S,0);} 
        for(int i=m+1;i<=n;++i) {add_edge(i,T,1);add_edge(T,i,0);} 
        int u,v;
        scanf("%d%d",&u,&v);
        while(u!=-1&&v!=-1)
        {
            add_edge(u,v,1);
            add_edge(v,u,0);
            scanf("%d%d",&u,&v);
        }
        dinic(S,T);
        if(Answer)
        {
            printf("%d
    ",Answer);
            for(int i=1;i<=m;++i)
                if(x[i]) 
                    printf("%d %d
    ",i,x[i]);
        }
        else printf("No Solution!");
        return 0;
    }
     
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    【Mysql学习笔记】浅析mysql的binlog
    HBase 学习笔记---守护进程及内存调优
    字符集例子-同一字符不同字符集编码不同及导入导出的乱码
    随机访问
    格式化的代价
    读写文本文件
    缓冲
    加速I/O的基本规则
    序列化再探讨
    数据库I/O:CMP、Hibernate
  • 原文地址:https://www.cnblogs.com/ruojisun/p/6505975.html
Copyright © 2020-2023  润新知