zoukankan      html  css  js  c++  java
  • 网络流24题——飞行员配对方案问题(二分图最大匹配)

    链接:https://www.oj.swust.edu.cn/oj/problem/show/1736

    分析:模板题,增加源点和汇点s、t,从s向U中所有点连一条容量为1的边,从V中所有点向t中所有点连一条容量为1的边,然后求s-t最大流即为所求。最大流用的isap模板。

      1 #include<iostream>
      2 #include<vector>
      3 #include<queue>
      4 #include<stack>
      5 #include<cstdio>
      6 #include<cstring>
      7 using namespace std;
      8 const int maxn=1e3+5,INF=1e9;
      9 struct Edge{
     10     int from,to,cap,flow;
     11     Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
     12 };
     13 struct ISAP{
     14     int n,s,t;
     15     vector<Edge> edges;
     16     vector<int> G[maxn];
     17     bool vis[maxn];
     18     int d[maxn];
     19     int cur[maxn];
     20     int p[maxn];
     21     int num[maxn];
     22 
     23     void init(int n){
     24         this->n=n;
     25         edges.clear();
     26         for(int i=0;i<n;i++)G[i].clear();
     27     }
     28 
     29     void AddEdge(int from,int to,int cap){
     30         edges.push_back(Edge(from,to,cap,0));
     31         edges.push_back(Edge(to,from,0,0));
     32         G[from].push_back(edges.size()-2);
     33         G[to].push_back(edges.size()-1);
     34     }
     35 
     36     void BFS(){
     37         memset(vis,0,sizeof(vis));
     38         queue<int> Q;
     39         Q.push(t);
     40         d[t]=0;
     41         vis[t]=1;
     42         while(!Q.empty()){
     43             int x=Q.front();Q.pop();
     44             for(int i=0;i<G[x].size();i++){
     45                 Edge &e=edges[G[x][i]];
     46                 if(!vis[e.to]){
     47                     vis[e.to]=1;
     48                     d[e.to]=d[x]+1;
     49                     Q.push(e.to);
     50                 }
     51             }
     52         }
     53     }
     54 
     55     int Augment(){
     56         int x=t,a=INF;
     57         while(x!=s){
     58             Edge &e=edges[p[x]];
     59             a=min(a,e.cap-e.flow);
     60             x=edges[p[x]].from;
     61         }
     62         x=t;
     63         while(x!=s){
     64             edges[p[x]].flow+=a;
     65             edges[p[x]^1].flow-=a;
     66             x=edges[p[x]].from;
     67         }
     68         return a;
     69     }
     70 
     71     int Maxflow(int s,int t){
     72         this->s=s;this->t=t;
     73         int flow=0;
     74         BFS();
     75         memset(num,0,sizeof(num));
     76         for(int i=0;i<n;i++)num[d[i]]++;
     77         int x=s;
     78         memset(cur,0,sizeof(cur));
     79         while(d[s]<n){
     80             if(x==t){
     81                 flow+=Augment();
     82                 x=s;
     83             }
     84             int ok=0;
     85             for(int i=cur[x];i<G[x].size();i++){
     86                 Edge &e=edges[G[x][i]];
     87                 if(e.cap>e.flow&&d[x]==d[e.to]+1){
     88                     ok=1;
     89                     p[e.to]=G[x][i];
     90                     cur[x]=i;
     91                     x=e.to;
     92                     break;
     93                 }
     94             }
     95             if(!ok){
     96                 int m=n-1;
     97                 for(int i=0;i<G[x].size();i++){
     98                     Edge &e=edges[G[x][i]];
     99                     if(e.cap>e.flow)m=min(m,d[e.to]);
    100                 }
    101                 if(--num[x]==0)break;
    102                 num[d[x]=m+1]++;
    103                 cur[x]=0;
    104                 if(x!=s)x=edges[p[x]].from;
    105             }
    106         }
    107         return flow;
    108     }
    109 }isap;
    110 
    111 int main(){
    112 //    freopen("input.txt","r",stdin);
    113     //freopen("output.txt","w",stdout);
    114     int n,m,s,t;
    115     scanf("%d%d",&m,&n);
    116     isap.init(n+1);
    117     for(int i=1;i<=m;i++)isap.AddEdge(0,i,1);
    118     for(int i=m+1;i<=n;i++)isap.AddEdge(i,n+1,1);
    119     while(1){
    120         scanf("%d%d",&s,&t);
    121         if(s==-1&&t==-1)break;
    122         isap.AddEdge(s,t,1);
    123     }
    124     int M=isap.Maxflow(0,n+1);
    125     if(M==0){
    126         printf("No Solution!
    ");
    127     }else{
    128         printf("%d
    ",M);
    129         for(int i=0;i<isap.edges.size();i++){
    130             if(isap.edges[i].from!=0&&isap.edges[i].to!=n+1&&isap.edges[i].flow==1){
    131                 printf("%d %d
    ",isap.edges[i].from,isap.edges[i].to);
    132             }
    133         }
    134     }
    135     return 0;
    136 }
  • 相关阅读:
    Request源码总结
    jmeter并发顺序问题
    mysql函数应用
    读《飘》之后的感受
    itchat源码阅读一
    python将print的内容输出到txt文件
    说一下StoreBoard和纯代码编程各有什么好处吧
    CocoaPods 安装
    Silverlight调用WebSite类型的WebService,Debug时的跨域问题
    ComboBox的奇怪属性
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7448017.html
Copyright © 2011-2022 走看看