标签:
PS:SDOI2016 Round1滚粗后蒟蒻开始做网络流来自我拯救(2016-04-11再过几天就要考先修课,现在做网络流24题貌似没什么用←退役节奏)
做的题目将附上日期,见证我龟速刷题。
1.飞行员配对方案问题 2016-04-11
二分图最大匹配问题,更新了一下$Dinic$模板,带上了当前弧优化和多路增广。这道题输出方案有很多种,可是没有special judge,所以没有A,但方案数是对的。合法的输出方案只能用匈牙利算法解决。
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> #define read(x) x=getint() using namespace std; const int N = 1003; int getint() { int k = 0, fh = 1; char c = getchar(); for(; c < ‘0‘ || c > ‘9‘; c = getchar()) if (c == ‘-‘) fh = -1; for(; c >= ‘0‘ && c <= ‘9‘; c = getchar()) k = k * 10 + c - ‘0‘; return k * fh; } queue<int> q; bool vis[N]; int point[N], cap[N], nxt[N], to[N], d[N], cur[N], S, T, cnt = 1; bool BFS() { memset(vis, 0, sizeof(vis)); q.push(S); d[S] = 0; vis[S] = 1; int u, i; while (!q.empty()) { u = q.front(); q.pop(); for(i = point[u]; i; i = nxt[i]) if (!vis[to[i]] && cap[i]) { d[to[i]] = d[u] + 1; vis[to[i]] = 1; q.push(to[i]); } } return vis[T]; } int DFS(int u, int a) { if (u == T || !a) return a; int f, flow = 0; for(int i = cur[u]; i; i = nxt[i]) if (d[u] + 1 == d[to[i]] && (f = DFS(to[i], min(a, cap[i]))) > 0) { flow += f; a -= f; cap[i] -= f; cap[i ^ 1] += f; if (!a) break; } return flow; } int Dinic() { int flow = 0, i; while (BFS()) { for(i = 1; i <= T; ++i) cur[i] = point[i]; flow += DFS(S, 0x7fffffff); } return flow; } void ins(int x, int y, int z) { nxt[++cnt] = point[x]; to[cnt] = y; cap[cnt] = z; point[x] = cnt; } void findpair(int x) { for(int i = point[x]; i; i = nxt[i]) if (cap[i] == 0 && to[i] != S) {printf("%d %d\n", x, to[i]); break;} } int main() { int n, m; read(n); read(m); S = n + m + 1; T = S + 1; for(int i = 1; i <= n; ++i) ins(S, i, 1), ins(i, S, 0); for(int i = n + 1; i <= n + m; ++i) ins(i, T, 1), ins(T, i, 0); int u, v; read(u); read(v); while (u != -1 && v != -1) { ins(u, v, 1); ins(v, u, 0); read(u); read(v); } printf("%d\n", Dinic()); for(int i = 1; i <= n; ++i) findpair(i); return 0; }
标签:
原文地址:http://www.cnblogs.com/abclzr/p/5380247.html