〜アンは、ここでポータルの兆候を示している:羅区P2756パイロットプログラムは、問題をペアリング
問題の解決策
それは明らかであるネットワークの最大フロー、それの。または必要なマッチの最大数に一致する二部グラフ。
Sが外部パイロットに接続されている間、二部グラフを構築し、さらにTブリティッシュパイロットつつ、エッジの重みも関係側、右側INF、ランニングのような最大流量に被験者によれば、1です。それは、それぞれが外国人パイロットに貢献していると理解することができますが、T.に、その後イギリスのパイロットを選択します 【その二部グラフの最大マッチングされません。]二部グラフとそうも書き込むことができます。ここでは、ネットワークフロー、および優れたライティングの使用に関する。
そして、問題は、出力方式にされています。シンプルああ、右側の英国側、あるいは外国人パイロットに各外来または英国のパイロットを見ては、完全な流れ、逆流は、その後、2機の航空機と会うがあるかどうかを見ているかどうか見ています。
コード -
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define maxn 500
#define maxm 200005
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int read() {
int x = 0, f = 1, ch = getchar();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
return x * f;
}
struct edge {int to, w, nxt;} e[maxm];
int head[maxn], k = 0;
void add(int u, int v, int w) {
e[k] = {v, w, head[u]}; head[u] = k++;
e[k] = {u, 0, head[v]}; head[v] = k++;
}
int n, m;
int d[maxn], S, T;
bool bfs() {
memset(d, 0, sizeof d); d[S] = 1;
queue<int> q; q.push(S);
while(q.size()) {
register int u = q.front(), v; q.pop();
for(int i = head[u]; ~i; i = e[i].nxt) {
v = e[i].to; if(e[i].w && !d[v]) {
d[v] = d[u] + 1; q.push(v);
if(v == T) return true;
}
}
}
return false;
}
int Dinic(int u, int flow) {
if(u == T) return flow;
register int res = flow, k;
for(int i = head[u], v; ~i; i = e[i].nxt) {
v = e[i].to; if(e[i].w && d[v] == d[u] + 1) {
k = Dinic(v, min(res, e[i].w));
if(!k) d[v] = 0;
e[i].w -= k, e[i ^ 1].w += k;
res -= k;
}
}
return flow - res;
}
signed main() {
memset(head, -1, sizeof head);
m = read(), n = read();
register int u, v, tot = 0;
while(u = read(), v = read()) {
if(u == -1) break;
add(u, v, INF); tot += 2;//记录图中间的边是从0~tot-1
}
S = 0, T = n + 1;
for(int i = 1; i <= m; i++) add(S, i, 1);
for(int i = m + 1; i <= n; i++) add(i, T, 1);
register int flow, ans = 0;
while(bfs()) while(flow = Dinic(S, INF)) ans += flow;
if(!ans) {puts("No Solution!"); return 0;}//一架都配不了
printf("%d\n", ans);
for(int i = 0; i < tot; i += 2) //这里判断的是逆边,其实SPJ下顺序都无所谓的
if(e[i ^ 1].w) printf("%d %d\n", e[i].to, e[i ^ 1].to);
return 0;
}
ミート評価
:) --End--