飞行员配对方案问题 【网络流24题】

 

 

 

输入输出样例

输入 #1<button class="copy&#45;btn lfe&#45;form&#45;sz&#45;middle" data&#45;v&#45;370e72e2="" data&#45;v&#45;52f2d52f="" type="button">复制</button>
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<button class="copy&#45;btn lfe&#45;form&#45;sz&#45;middle" data&#45;v&#45;370e72e2="" data&#45;v&#45;52f2d52f="" type="button">复制</button>
4
1 7
2 9
3 8
5 10

 

 

思路

  题目给出两个不同阵营

  不同阵营之间的人可以组队

  一个人只能和一个人组队

  求最大匹配数

  显然可以直接偷懒上匈牙利

  但既然叫网络流24题就用网络流做吧

  建立一个S、一个T表示超级源、汇

  把A阵营的人连S

  B阵营的人连T

  认识的人之间就可以连边

  因为每个人都只能和一个另外阵营的人组队

  说明每个点都只能最多用一次

  所以这些边的 capacity 都是 1

  图建完后,如何输出他们匹配的方案呢

  考虑最小路径那样记录

  但是由于悔边的原因并不好记录

  所以直接从悔边下手

  当一对组合成立

  说明正向边容量 - 1

  则悔边容量应该 + 1

  所以只要是悔边容量变大了的

  那么连着这条边的两个人都是被选中的

  

CODE

 

  1 #include <bits/stdc++.h>
  2 #define dbg(x) cout << #x << "=" << x << endl
  3 #define eps 1e-8
  4 #define pi acos(-1.0)
  5 
  6 using namespace std;
  7 typedef long long LL;
  8 
  9 const int inf = 0x3f3f3f3f;
 10 
 11 template<class T>inline void read(T &res)
 12 {
 13     char c;T flag=1;
 14     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
 15     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
 16 }
 17 
 18 namespace _buff {
 19     const size_t BUFF = 1 << 19;
 20     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
 21     char getc() {
 22         if (ib == ie) {
 23             ib = ibuf;
 24             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
 25         }
 26         return ib == ie ? -1 : *ib++;
 27     }
 28 }
 29 
 30 int qread() {
 31     using namespace _buff;
 32     int ret = 0;
 33     bool pos = true;
 34     char c = getc();
 35     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
 36         assert(~c);
 37     }
 38     if (c == '-') {
 39         pos = false;
 40         c = getc();
 41     }
 42     for (; c >= '0' && c <= '9'; c = getc()) {
 43         ret = (ret << 3) + (ret << 1) + (c ^ 48);
 44     }
 45     return pos ? ret : -ret;
 46 }
 47 
 48 const int maxn = 200007;
 49 
 50 int n, m;
 51 int s, t;
 52 
 53 struct edge{
 54     int from,to;
 55     LL cap,flow;
 56 };
 57 
 58 map<int, int> vis;
 59 
 60 struct DINIC {
 61     int head[maxn << 1], nxt[maxn << 1], edge[maxn << 1], cnt;
 62     int cap[maxn << 1], depth[maxn << 1];
 63 
 64     void init() {
 65         cnt = 1;
 66         memset(head, 0, sizeof(head));
 67     }
 68 
 69     void BuildGraph(int u, int v, int w) {
 70         ++cnt;
 71         edge[cnt] = v;
 72         nxt[cnt] = head[u];
 73         cap[cnt] = w;
 74         head[u] = cnt;
 75 
 76         ++cnt;
 77         edge[cnt] = u;
 78         nxt[cnt] = head[v];
 79         cap[cnt] = 0;
 80         head[v] = cnt;
 81     }
 82 
 83     queue<int> q;
 84 
 85     bool bfs() {
 86         memset(depth, 0, sizeof(depth));
 87         depth[s] = 1;
 88         q.push(s);
 89         while(!q.empty()) {
 90             int u = q.front();
 91             q.pop();
 92             for ( int i = head[u]; i; i = nxt[i] ) {
 93                 int v = edge[i];
 94                 if(depth[v]) {
 95                     continue;
 96                 }
 97                 if(cap[i]) {
 98                     depth[v] = depth[u] + 1;
 99                     q.push(v);
100                 }
101             }
102         }
103         return depth[t];
104     }
105 
106     int dfs(int u, int dist) {
107         if(u == t) {
108             return dist;
109         }
110         int flow = 0;
111         for ( int i = head[u]; i && dist; i = nxt[i] ) {
112             if(cap[i] == 0)
113                 continue;
114             int v = edge[i];
115             if(depth[v] != depth[u] + 1) {
116                 continue;
117             }
118             int res = dfs(v, min(cap[i], dist));
119             cap[i] -= res;
120             cap[i ^ 1] += res;
121             //printf("cap[%d]:%d\n",t, cap[t]);
122             vis[u] = v;
123             dist -= res;
124             flow += res;
125         }
126         return flow;
127     }
128 
129     int maxflow() {
130         int ans = 0;
131         while(bfs()) {
132             ans += dfs(s, inf);
133         }
134         return ans;
135     }
136 } dinic;
137 
138 int main()
139 {
140     //freopen("data.txt", "r", stdin);
141     read(m); read(n); 
142     int u, v;
143     s = 0, t = n + m + 1;
144     dinic.init();
145     while(1) {
146         read(u); read(v);
147         if(u == -1 && v == -1) {
148             break;
149         }
150         dinic.BuildGraph(u, v, 1);
151     }
152     for ( int i = 1; i <= m; ++i ) {
153         dinic.BuildGraph(s, i, 1);
154     }
155     for ( int i = m + 1; i <= m + n; ++i ) {
156         dinic.BuildGraph(i, t, 1);
157     }
158     cout << dinic.maxflow() << endl;
159     int tot = dinic.cnt;
160     for ( int i = 2; i <= tot; i += 2 ) {
161         int u = dinic.edge[i];
162         int v = dinic.edge[i ^ 1];
163         if(u == s || u == t || v == s || v == t) {
164             continue;
165         }
166         else {
167             int cap = dinic.cap[i ^ 1];
168             if(cap != 0) {
169                 printf("%d %d\n",v, u);
170             }
171         }
172     }
173     return 0;
174 }
View Code

 

 

 

#include  < bits/stdc++.h >
#define  dbg( x ) cout  <<  #x  <<  " = "  << x  << endl
#define  eps  1 e - 8
#define  pi  acos( - 1.0 )

using  namespace std ;
typedef  long  long LL ;

const  int inf  =  0x 3f3f3f3f ;

template < class T > inline  void  read(& res )
{
     char c ;T flag = 1 ;
     while((c = getchar()) < ' 0 ' ||c > ' 9 ' )if(c == ' - ' )flag =- 1 ;res =c - ' 0 ' ;
     while((c = getchar()) >= ' 0 ' &&c <= ' 9 ' )res =res * 10 +c - ' 0 ' ;res *=flag ;
}

namespace _buff  {
     const  size_t BUFF  =  1  <<  19 ;
     char  ibuf [BUFF ],  *ib  = ibuf ,  *ie  = ibuf ;
     char  getc()  {
         if  (ib  == ie )  {
            ib  = ibuf ;
            ie  = ibuf  +  fread(ibuf ,  1 , BUFF , stdin );
         }
         return ib  == ie  ?  - 1  :  *ib ++ ;
     }
}

int  qread()  {
     using  namespace _buff ;
     int ret  =  0 ;
     bool pos  =  true ;
     char c  =  getc();
     for  (;  (<  ' 0 '  || c  >  ' 9 ' )  && c  !=  ' - ' ; c  =  getc())  {
         assert( ~c );
     }
     if  (==  ' - ' )  {
        pos  =  false ;
        c  =  getc();
     }
     for  (; c  >=  ' 0 '  && c  <=  ' 9 ' ; c  =  getc())  {
        ret  =  (ret  <<  3 )  +  (ret  <<  1 )  +  (^  48 );
     }
     return pos  ? ret  :  -ret ;
}

const  int maxn  =  200007 ;

int n , m ;
int s , t ;

struct edge {
     int from ,to ;
    LL cap ,flow ;
};

map <int ,  int> vis ;

struct DINIC  {
     int  head [maxn  <<  1 ],  nxt [maxn  <<  1 ],  edge [maxn  <<  1 ], cnt ;
     int  cap [maxn  <<  1 ],  depth [maxn  <<  1 ];

     void  init()  {
        cnt  =  1 ;
         memset(head ,  0 ,  sizeof (head ));
     }

     void  BuildGraph( int  u ,  int  v ,  int  w )  {
         ++cnt ;
         edge [cnt ]  = v ;
         nxt [cnt ]  =  head [u ];
         cap [cnt ]  = w ;
         head [u ]  = cnt ;

         ++cnt ;
         edge [cnt ]  = u ;
         nxt [cnt ]  =  head [v ];
         cap [cnt ]  =  0 ;
         head [v ]  = cnt ;
     }

    queue <int> q ;

     bool  bfs()  {
         memset(depth ,  0 ,  sizeof (depth ));
         depth [s ]  =  1 ;
         q .push(s );
         while( ! q .empty())  {
             int u  =  q .front();
             q .pop();
             for  (  int i  =  head [u ]; i ; i  =  nxt [i ]  )  {
                 int v  =  edge [i ];
                 if( depth [v ])  {
                     continue;
                 }
                 if( cap [i ])  {
                     depth [v ]  =  depth [u ]  +  1 ;
                     q .push(v );
                 }
             }
         }
         return  depth [t ];
     }

     int  dfs( int  u ,  int  dist )  {
         if(== t )  {
             return dist ;
         }
         int flow  =  0 ;
         for  (  int i  =  head [u ]; i  && dist ; i  =  nxt [i ]  )  {
             if( cap [i ]  ==  0 )
                 continue;
             int v  =  edge [i ];
             if( depth [v ]  !=  depth [u ]  +  1 )  {
                 continue;
             }
             int res  =  dfs(v ,  min( cap [i ], dist ));
             cap [i ]  -= res ;
             cap [^  1 ]  += res ;
            //printf("cap[%d]:%d\n",t, cap[t]);
             vis [u ]  = v ;
            dist  -= res ;
            flow  += res ;
         }
         return flow ;
     }

     int  maxflow()  {
         int ans  =  0 ;
         while(bfs())  {
            ans  +=  dfs(s , inf );
         }
         return ans ;
     }
} dinic ;

int  main()
{
    //freopen("data.txt", "r", stdin);
     read(m );  read(n ); 
     int u , v ;
    s  =  0 , t  = n  + m  +  1 ;
     dinic .init();
     while( 1 )  {
         read(u );  read(v );
         if(==  - 1  && v  ==  - 1 )  {
             break;
         }
         dinic .BuildGraph(u , v ,  1 );
     }
     for  (  int i  =  1 ; i  <= m ;  ++)  {
         dinic .BuildGraph(s , i ,  1 );
     }
     for  (  int i  = m  +  1 ; i  <= m  + n ;  ++)  {
         dinic .BuildGraph(i , t ,  1 );
     }
    cout  <<  dinic .maxflow()  << endl ;
     int tot  =  dinic . cnt ;
     for  (  int i  =  2 ; i  <= tot ; i  +=  2  )  {
         int u  =  dinic . edge [i ];
         int v  =  dinic . edge [^  1 ];
         if(== s  || u  == t  || v  == s  || v  == t )  {
             continue;
         }
         else  {
             int cap  =  dinic . cap [^  1 ];
             if(cap  !=  0 )  {
                 printf( " %d   %d \n " ,v , u );
             }
         }
     }
     return  0 ;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务