Fork me on GitHub

飞行员配对方案问题

飞行员配对方案问题

传送门

读完题,就知道这就是个裸的二分图皮配,然后,我还是不说匈牙利,(因为我真的不会啊!)

所以,我还是用了喜闻乐见的 $Dinic$ 并且跑的也不慢.唯一难点就是输出方案了吧…输出方案用最后的连通性判断,这题就没了….

$Code:$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>

const int N = 1e5 + 5 ;
const int INF = 1061109567 ;

using std::queue ;

struct edge { int to , next , flow ; } e[(N<<1)] ;

int tot = 1 , head[N] , flor[N] , s , t , n , m , x , y ;

inline void build (int u , int v ,int w) {
e[++tot].next = head[u] ; e[tot].to = v ;
e[tot].flow = w ; head[u] = tot ; return;
}

queue < int > q ;
inline bool bfs ( int cur ) {
while ( ! q.empty () ) q.pop () ;
memset ( flor , false , sizeof ( flor ) ) ;
q.push ( cur ) ; flor[cur] = 1 ;
while ( ! q.empty () ) {
int j = q.front () ; q.pop () ;
for (int i = head[j] ; i ; i = e[i].next) {
int k = e[i].to ;
if ( ! flor[k] && e[i].flow ) {
flor[k] = flor[j] + 1 ;
if ( k == t ) return flor[t] ;
q.push ( k ) ;
}
}
}
return flor[t] ;
}

inline int dfs (int cur , int dist) {
if ( cur == t ) return dist ;
for (int i = head[cur] ; i ; i = e[i].next) {
int k = e[i].to ;
if ( flor[k] == flor[cur] + 1 && e[i].flow ) {
int now = dfs ( k , std::min ( e[i].flow , dist ) ) ;
if ( now != 0 ) {
e[i].flow -= now ;
e[i^1].flow += now ;
return now ;
}
}
}
return 0 ;
}

inline int Dinic () {
int ans = 0 ;
while ( bfs ( s ) )
while ( int now = dfs ( s , INF ) )
ans += now ;
return ans ;
}

int main () {
scanf ("%d%d" , & m , & n ) ; s = 0 ; t = n + 1 ;
for (int i = 1 ; i <= m ; ++ i) build ( s , i , 1 ) , build ( i , s , 0 ) ; // 连外籍
for (int i = m + 1 ; i <= n ; ++ i) build ( i , t , 1 ) , build ( t , i , 0 ) ; // 连皇家
while ( scanf ("%d%d" , & x , & y ) && x != - 1 && y != - 1 )
build ( x , y , 1 ) , build ( y , x , 0 ) ;
int ans = Dinic () ;
if ( ! ans ) { puts ("No Solution!") ; return 0 ; }
printf ("%d\n" , ans ) ;
for (int i = 2 ; i <= tot ; i += 2)
if ( e[i].to != s && e[i^1].to != s )
if ( e[i].to != t && e[i^1].to != t )
if ( e[i^1].flow != 0 ) printf ("%d %d\n" , e[i^1].to , e[i].to ) ;
system ("pause") ; return 0 ;
}