放图片是不是很骚气
解题思路
建立超级源点和超级汇点。将主驾驶雨源点相连,副驾驶与汇点相连,再把输入的有向边加进去,同时建反边。
跑$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); }
原文地址:https://www.cnblogs.com/bljfy/p/9543665.html
时间: 2024-10-07 13:09:24