1. 程式人生 > >Loj #6000.「 網絡流 24 題 」搭配飛行員

Loj #6000.「 網絡流 24 題 」搭配飛行員

truct i++ depth main 網絡流 模板 while pri printf

放圖片是不是很騷氣

解題思路

建立超級源點和超級匯點。將主駕駛雨源點相連,副駕駛與匯點相連,再把輸入的有向邊加進去,同時建反邊。

跑$Dinic$,網絡流模板不難,難的是建模QAQ

附上代碼

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxnode = 105, maxedge = 30003, INF = 2147483647;
int n, m, s, t, head[maxnode], cnt = 1
, Depth[maxnode], Ans; struct Edge { int nxt, v, w; }ed[maxedge]; inline void addedge(int u, int v, int w) { ed[++cnt].nxt = head[u]; ed[cnt].v = v, ed[cnt].w = w; head[u] = cnt; } inline bool BFS() { queue <int> Q; memset(Depth, 0, sizeof(Depth)); Depth[s]
= 1, Q.push(s); int u; while (!Q.empty()) { u = Q.front(); Q.pop(); for(int i=head[u]; i; i=ed[i].nxt) { if(Depth[ed[i].v] == 0 && ed[i].w > 0) { Depth[ed[i].v] = Depth[u] + 1; Q.push(ed[i].v);
if(ed[i].v == t) return true; } } } return false; } inline int Dinic(int u, int cap) { if(u == t) return cap; int delta; for(int i=head[u]; i; i=ed[i].nxt) { if(ed[i].w > 0 && Depth[ed[i].v] == Depth[u] + 1) { delta = Dinic(ed[i].v, min(cap, ed[i].w)); if(delta > 0) { ed[i].w -= delta; ed[i^1].w += delta; return delta; } } } return 0; } int main() { scanf("%d%d", &n, &m); s = 0, t = n+1; for(int i=1; i<=m; i++) addedge(s, i, 1), addedge(i, s, 0); for(int i=m+1; i<=n; i++) addedge(i, t, 1), addedge(t, i, 0); static int x, y; while (scanf("%d%d", &x, &y) == 2) addedge(x, y, 1), addedge(y, x, 0); while (BFS()) Ans += Dinic(s, INF); printf("%d", Ans); }

Loj #6000.「 網絡流 24 題 」搭配飛行員