飞行员配对方案问题 【网络流24题】
输入输出样例
输入 #1<button class="copy-btn lfe-form-sz-middle" data-v-370e72e2="" data-v-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-btn lfe-form-sz-middle" data-v-370e72e2="" data-v-52f2d52f="" type="button">复制</button> View Code
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 }
#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(T & 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 (; (c < ' 0 ' || c > ' 9 ' ) && c != ' - ' ; c = getc()) {
assert( ~c );
}
if (c == ' - ' ) {
pos = false ;
c = getc();
}
for (; c >= ' 0 ' && c <= ' 9 ' ; c = getc()) {
ret = (ret << 3 ) + (ret << 1 ) + (c ^ 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(u == 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 [i ^ 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(u == - 1 && v == - 1 ) {
break;
}
dinic .BuildGraph(u , v , 1 );
}
for ( int i = 1 ; i <= m ; ++i ) {
dinic .BuildGraph(s , i , 1 );
}
for ( int i = m + 1 ; i <= m + n ; ++i ) {
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 [i ^ 1 ];
if(u == s || u == t || v == s || v == t ) {
continue;
}
else {
int cap = dinic . cap [i ^ 1 ];
if(cap != 0 ) {
printf( " %d %d \n " ,v , u );
}
}
}
return 0 ;
}