码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-10-03 23:34:05      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的 2 名飞行员,其中 1 名是英国飞行员,另 1 名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。如何选择配对飞行的飞行员才能使一次派出最多的飞机。对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

输入描述 Input Description

第 1 行有 2 个正整数 m和 n。n 是皇家空军的飞行员总数(n<100);m 是外籍飞行员数。外籍飞行员编号为 1~m;英国飞行员编号为 m+1~n。接下来每行有 2 个正整数 i 和 j,表示外籍飞行员 i 可以和英国飞行员 j 配合。文件最后以 2个-1 结束。

输出描述 Output Description

 1 行是最佳飞行员配对方案一次能派出的最多的飞机数 M。接下来 M 行是最佳飞行员配对方案。每行有 2个正整数 i 和 j,表示在最佳飞行员配对方案中,飞行员 i 和飞行员 j 配对。如果所求的最佳飞行员配对方案不存在,则输出‘No Solution!’。

样例输入 Sample Input

5 10

1 7

1 8

2 6

2 9

2 10

3 7

3 8

4 7

4 8

5 10

-1 -1

样例输出 Sample Output

4

1 7

2 9

3 8

5 10

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <queue>
  7 using namespace std ;
  8 const int inf = 1<<30 , maxn = 10000 + 11 ;
  9 int m , n , head[1003] , cnt , dis[1001]  , s , t , cur[1001] , sum ; 
 10 struct id
 11 {
 12     int nxt , to , vi , fro;
 13 }edge[maxn<<1] ;
 14 struct A 
 15 {
 16     int a , b ;
 17 } ans[1001] ;
 18 
 19 queue< int > Q ;
 20 
 21 inline void Init( )
 22 {
 23     freopen( "air.in" , "r" , stdin ) ;
 24     freopen( "air.out" , "w" , stdout ) ;
 25 }
 26 
 27 
 28 void add( int a , int b , int c )
 29 {
 30     edge[++cnt].nxt = head[a] , edge[cnt].to = b ;
 31     edge[cnt].vi = c , head[a] = cnt ; edge[cnt].fro = a ;
 32 }
 33 
 34 
 35 int read( )
 36 {
 37     char  ch = getchar( ) ; int k = 1 , ret = 0 ;
 38     while( ch < 0 || ch > 9 ) { if( ch == - ) k = -1 ; ch = getchar( ) ; }
 39     while( ch >= 0 && ch <=9 ) ret = ret * 10 + ch - 0 , ch = getchar(  ) ;
 40     return ret * k ;
 41 }
 42 
 43 
 44 void input(  )
 45 {
 46     m = read( ) , n = read( ) ;
 47     int a, b ; cnt = 1 ;
 48     s = 100<<2 , t = 100<<2 + 1 ;
 49     memset( head , -1 , sizeof(head)) ;
 50     while( 1 )
 51     {
 52         a = read( ) , b = read( ) ;
 53         if( a == -1 && b == -1 ) break ;
 54         add( a , b  , inf ) ; add( b , a , 0 ) ;
 55     }
 56     for( int x = 1 ; x <= m ; x++ ) 
 57     {
 58         add( s , x , 1 ) ;
 59         add( x , s , 0 ) ;
 60     }
 61     for( int x = 1 ; x <= m ; ++x )
 62     {
 63         add( x+m , t , 1 ) ;
 64         add( t , x+m , 0 ) ;
 65     } 
 66 }
 67 
 68 
 69 bool bfs(  )
 70 {
 71     memset( dis , -1 , sizeof(dis) ) ;
 72     Q.push( s ) ; dis[s] = 0 ;
 73     while( !Q.empty( ) )
 74     {
 75         int u = Q.front( ) ; Q.pop( ) ;
 76         for( int i = head[u] ; ~i ; i = edge[i].nxt )
 77         {
 78             int v = edge[i].to ;
 79             if( dis[v] < 0 && edge[i].vi > 0 )
 80             {
 81                 dis[v] = dis[u] + 1 ;
 82                 Q.push( v ) ;
 83             }
 84         }
 85     }
 86     return dis[t] > 0 ;
 87 }
 88 
 89 
 90 int dfs( int u , int tmp )
 91 {
 92     if( u == t ) return tmp ;
 93     int cost = 0 , an = 0 ;
 94     for( int i = cur[u] ; ~i ; i = edge[i].nxt )
 95     {
 96         int v = edge[i].to ; 
 97         if( dis[v] != dis[u] + 1 ) continue ;
 98         an = dfs( v , min( tmp - cost , edge[i].to) ) ;
 99         edge[i].vi -= an ; edge[i^1].vi += an ;
100         if( edge[i].vi ) cur[u] = i ;
101         cost += an ;
102         if( cost == tmp ) return cost ;    
103     }
104     if( !cost ) dis[u] = -1 ;
105     return cost ;
106 }
107 
108 
109 
110 void sov( )
111 {
112     while( bfs( ) ) 
113     {
114         for( int x = 1 ; x <= m << 1 ; ++x ) cur[x] = head[x] ;
115         sum += dfs( s , inf ) ;    
116     }
117 }
118 
119 
120 bool cmp( A a , A b )
121 {
122     if( a.a < b.a ) return 1 ;
123     if( a.a == b.a && a.b < b.b ) return 1 ;
124     return 0 ;
125 }
126 
127 
128 void output(  )
129 {
130     if( !ans )
131     {
132         printf( "No Solution!\n" ) ;
133         return ;
134     }
135     printf( "%d\n" , ans ) ; int tot = 0 ;
136     for( int x = 2 ; x <= cnt ; ++x )
137     {
138         if( !edge[x].vi && edge[x].fro != s && edge[x].nxt != t && edge[x].fro != t && edge[x].to != s && edge[x].fro < edge[x].to )
139             ans[++tot].a = edge[x].fro , ans[tot].b = edge[x].to ;
140     }
141     sort( ans + 1 , ans + 1 + tot , cmp ) ;
142     for( int x = 1 ; x <= tot ; x++ ) printf( "%d %d\n" , ans[x].a , ans[x].b ) ;
143 }
144 
145 
146 
147 int main( )
148 {
149     Init( ) ;
150     input( ) ;
151     sov( ) ;
152     output( ) ;
153     fclose( stdin ) ;
154     fclose( stdout ) ;
155     return 0 ;
156 }

好的没去测,存一份代码 ,

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

标签:

原文地址:http://www.cnblogs.com/Ateisti/p/5929671.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!