标签:
第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的 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!’。
5 10
1 7
1 8
2 6
2 9
2 10
3 7
3 8
4 7
4 8
5 10
-1 -1
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 }
好的没去测,存一份代码 ,
标签:
原文地址:http://www.cnblogs.com/Ateisti/p/5929671.html