• [网络流24题]飞行员配对方案问题


    P2756 飞行员配对方案问题
    题目提供者yyy2015c01
    题目背景
    第二次世界大战时期..
    题目描述
    英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的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

    /*
    最大流.
    这题各大OJ都没找到spj.
    qwq.
    还是二分图搞.
    这题加了一个print.
    找满流的边记下来输出即可.
    可是没有spj.... 
    */
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define MAXN 10001
    using namespace std;
    struct data{int v,next,c;}e[MAXN*2];
    int n,m,max1=1e9,ans,tot,cut=1,dis[MAXN],head[MAXN],next[MAXN];
    bool in[MAXN];
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int u,int v,int x)
    {
        e[++cut].v=v;
        e[cut].c=x;
        e[cut].next=head[u];
        head[u]=cut;
    }
    bool bfs()
    {
        memset(dis,-1,sizeof dis);
        queue<int>q;
        q.push(0);
        dis[0]=0;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head[u];i;i=e[i].next)
            {
                int v=e[i].v;
                if(dis[v]==-1&&e[i].c)
                {
                    dis[v]=dis[u]+1;
                    q.push(v);
                }
            }
        }
        return dis[n+1]!=-1;
    }
    int dfs(int u,int y)
    {
        if(u==n+1) return y;
        int rest=0;
        for(int i=head[u];i&&rest<y;i=e[i].next)
        {
            int v=e[i].v;
            if(dis[v]==dis[u]+1&&e[i].c)
            {
                int x=dfs(v,min(e[i].c,y-rest));
                rest+=x;
                e[i].c-=x;
                e[i^1].c+=x;
            }
        }
        if(!rest) dis[u]=-1;
        return rest;
    }
    void dinic(int s,int t)
    {
        while(bfs()) ans+=dfs(s,max1);
        printf("%d
    ",ans);
        return ;
    }
    void print()
    {
        for(int u=1;u<=n;u++)
          for(int i=head[u];i;i=e[i].next)
          {
              int v=e[i].v;
              if(e[i].c==max1-1) in[v]=true,next[u]=v;
          }
        for(int i=1;i<=n;i++)
        {
            int x=i;
            if(!in[x]&&next[x])
            {
              while(x) printf("%d ",x),x=next[x];
              printf("
    ");
            }
        }
    }
    int main()
    { 
        int x,y;
        m=read(),n=read();
        for(int i=1;i<=m;i++) add(0,i,1),add(i,0,0);
        for(int i=m+1;i<=n;i++) add(i,n+1,1),add(n+1,i,0);
        while(scanf("%d %d",&x,&y))
        {
            if(x==-1&&y==-1) break;
            add(x,y,max1),add(y,x,0);
        }
        dinic(0,n+1);
        print();
        return 0;
    }
  • 相关阅读:
    【矩阵】
    关于集合的思路
    TSQL生成Combguid
    ServiceLocator是反模式
    使用表达式树创建对象
    TeamCity配置笔记
    AutoMapper映射ExpressionTree
    Automapper扩展方法
    Cache&Session Viewer
    Orchard源码:Logging
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068140.html
Copyright © 2020-2023  润新知