• luogu P2756 飞行员配对方案问题


    题目链接: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 

    My Solution

    我还不会二分图匹配啊啊啊

    设源点s=0,汇点t=n+1

    s连1~m,m+1~n连t

    对于每组关系from,to,from连to

    流量都为一

    无脑打Dinic

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<vector>
      5 #include<queue>
      6 #define inf 0x3f3f3f3f
      7 using namespace std;
      8 
      9 inline int read(){
     10     int re=0;
     11     char ch;
     12     bool flag=0;
     13     while((ch=getchar())!='-'&&(ch<'0'||ch>'9'));
     14     ch=='-'?flag=1:re=ch-'0';
     15     while((ch=getchar())>='0'&&ch<='9')  re=re*10+ch-'0';
     16     return flag?-re:re;
     17 }
     18 
     19 struct edge{
     20     int from,to,cap,flow;
     21     edge(int from=0,int to=0,int cap=0,int flow=0):
     22         from(from),to(to),cap(cap),flow(flow){}
     23 };
     24 
     25 const int maxn=102;
     26 int n,m;
     27 int s,t;
     28 int nedge;
     29 vector<edge> edges;
     30 vector<int> G[maxn];
     31 bool vis[maxn];
     32 int d[maxn];
     33 int cur[maxn];
     34 
     35 inline void add_edge(int from,int to,int cap){
     36     edges.push_back(edge(from,to,cap,0));
     37     edges.push_back(edge(to,from,0,0));
     38     nedge=edges.size();
     39     G[from].push_back(nedge-2);
     40     G[to].push_back(nedge-1);
     41 }
     42 
     43 void init(){
     44     m=read(),n=read();
     45     s=0,t=n+1;
     46     for(int i=1;i<=m;i++)
     47         add_edge(s,i,1);
     48     for(int i=m+1;i<=n;i++)
     49         add_edge(i,t,1);
     50     while(1){
     51         int from=read(),to=read();
     52         if(from==-1)  break;
     53         add_edge(from,to,1);
     54     }
     55 }
     56 
     57 bool bfs(){
     58     memset(vis,0,sizeof vis);
     59     queue<int> que;
     60     que.push(s);
     61     d[s]=0;
     62     vis[s]=1;
     63     while(!que.empty()){
     64         int x=que.front();  que.pop();
     65         int dd=G[x].size();
     66         for(int i=0;i<dd;i++){
     67             edge &e=edges[G[x][i]];
     68             if(!vis[e.to]&&e.cap>e.flow){
     69                 vis[e.to]=1;
     70                 d[e.to]=d[x]+1;
     71                 que.push(e.to);
     72             }
     73         }
     74     }
     75     return vis[t];
     76 }
     77 
     78 int dfs(int x,int a){
     79     if(x==t||a==0)  return a;
     80     int flow=0,f;
     81     int dd=G[x].size();
     82     for(register int i=cur[x];i<dd;i++){
     83         edge &e=edges[G[x][i]];
     84         if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
     85             e.flow+=f;
     86             edges[G[x][i]^1].flow-=f;
     87             flow+=f;
     88             a-=f;
     89             if(a==0)  break;
     90         }
     91     }
     92     return flow;
     93 }
     94 
     95 int Maxflow(){
     96     int flow=0;
     97     while(bfs()){
     98         memset(cur,0,sizeof cur);
     99         flow+=dfs(s,inf);
    100     }
    101     return flow;
    102 }
    103 
    104 int main(){
    105     //freopen("temp.in","r",stdin);
    106     init();
    107     printf("%d
    ",Maxflow());
    108     for(register int i=1;i<=m;i++){
    109         int dd=G[i].size();
    110         for(register int j=0;j<dd;j++)
    111             if(edges[G[i][j]].flow&&edges[G[i][j]].to)
    112                 printf("%d %d
    ",i,edges[G[i][j]].to);
    113     }
    114     return 0;
    115 }

    如果梦想有颜色,那一定是水蓝色

  • 相关阅读:
    【每日一学】pandas_透视表函数&交叉表函数
    【Excel技能】字符串包含某字符串个数?替换许多组字符串?
    【SQL函数】我知道你想group_concat和count一起用,比如不同组合的人数?
    mysql大纲
    【Excel】绘图案例_常见复合图:簇状图+堆积图+折线图
    【统计分析方法】1.统计学知识图谱
    【统计分析方法】知识图谱(主要是统计推断部分)
    python之前期常用的内置函数
    python之匿名函数,函数递归
    python之三元表达式、列表生成式、字典表达式、生成器表达式
  • 原文地址:https://www.cnblogs.com/ZYBGMZL/p/6847361.html
Copyright © 2020-2023  润新知