zoukankan      html  css  js  c++  java
  • 【网络流】——P2756 飞行员配对方案问题

    简单的二分图匹配问题。

    GO:洛谷


    水水就过了。

    配对方案从边里面找:

    1. 一定是权值为0的边
    2. 源点一定在1~m间,汇点一定在m+1~n间
    3. 直接输出即可。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1100;
     4 const int inf=1e9;
     5 int m,n,S,T,cnt=-1,maxflow;
     6 int d[N],head[N<<1];
     7 struct edge{int to,next,f,from;}e[N<<1];
     8 void addedge(int from,int to,int f){e[++cnt]=(edge){to,head[from],f,from};head[from]=cnt;}
     9 inline bool bfs(){
    10     memset(d,0,sizeof(d));
    11     queue<int>q;
    12     q.push(S);
    13     d[S]=1;
    14     while(q.size()){
    15         int u=q.front();
    16         q.pop();
    17         for(int i=head[u];i!=-1;i=e[i].next){
    18             int v=e[i].to,f=e[i].f;
    19             if(d[v]||!f) continue;
    20             d[v]=d[u]+1;
    21             q.push(v);
    22             if(v==T) return 1;
    23         }
    24     }
    25     return 0;
    26 }
    27 
    28 int dinic(int u,int flow){
    29     if(u==T) return flow;
    30     int rest=flow;
    31     for(int i=head[u];i!=-1&&rest;i=e[i].next){
    32         int v=e[i].to,f=e[i].f;
    33         if(!f||d[v]!=d[u]+1) continue;
    34         int k=dinic(v,min(rest,f));
    35         if(!k) d[v]=0;
    36         else{
    37             e[i].f-=k;
    38             e[i^1].f+=k;
    39             rest-=k;
    40         }
    41     }
    42     return flow-rest;
    43 }
    44 void solve(){
    45     int now=0;
    46     while(bfs()){
    47         while(now=dinic(S,inf))
    48             maxflow+=now;
    49     }
    50     if(!maxflow){
    51         printf("No Solution!");
    52     }
    53     else{
    54         printf("%d\n",maxflow);
    55         for(int i=0;i<=cnt;i++){
    56             if(!e[i].f&&e[i].from>0&&e[i].from<=m&&e[i].to>m&&e[i].to<=n){
    57                 printf("%d %d\n",e[i].from,e[i].to);
    58             }
    59         }
    60     }
    61 }
    62 int main(){
    63     memset(head,-1,sizeof(head));
    64     scanf("%d%d",&m,&n);
    65     int x=0,y=0;
    66     S=0,T=n+1;
    67     while(1){
    68         scanf("%d%d",&x,&y);
    69         if(x<0) break;
    70         addedge(x,y,1);
    71         addedge(y,x,0);
    72     }
    73     for(int i=1;i<=m;i++){
    74         addedge(S,i,1);
    75         addedge(i,S,0);
    76     }
    77     for(int i=m+1;i<=n;i++){
    78         addedge(i,T,1);
    79         addedge(T,i,0);
    80     }
    81     solve();
    82     return 0;
    83 }

    切题真爽!

    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    消息队列介绍
    SpringBoot随笔-SpringBoot集成Druid
    Redis-Redis基本类型及使用Java操作
    信息安全
    计算机网络基础
    多媒体技术
    数据库基础
    程序设计基础
    计算机软件体系
    计算机硬件体系
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11370348.html
Copyright © 2011-2022 走看看