我做的是这道题 最小路径覆盖问题 (网络流),代码中使用的是 Dinic 算法,程序在最后一行异常退出,详见 提交记录。
#include <iostream>
#include <queue>
#include <cstring>
#include <climits>
#include <map>
using namespace std;
const int Max = 2000;
int n, m, s, t, ans, flow, dis[Max], to[Max];
map<int, int> g[Max];
bool d[Max];
bool bfs() {
memset(dis, 0, sizeof dis);
queue<int> q;
q.push(s);
dis[s] = 1;
while (!q.empty()) {
auto x = q.front();
q.pop();
if (x == t)
return true;
for (auto y: g[x])
if (y.second && !dis[y.first]) {
dis[y.first] = dis[x] + 1;
q.push(y.first);
}
}
return false;
}
int dinic(int x, int _flow) {
if (x == t)
return _flow;
int rest = _flow;
for (auto y: g[x])
if (rest && y.second && dis[y.first] == dis[x] + 1) {
int f = dinic(y.first, min(rest, y.second));
if (!f)
dis[y.first] = -1;
else {
if (x != s)
d[y.first - n] = true;
to[x] = y.first;
rest -= f;
g[x][y.first] -= f;
g[y.first][x] += f;
}
}
return _flow - rest;
}
int main() {
cin >> n >> m;
s = 0;
t = n + n + 1;
for (int i = 1; i <= n; i++) {
g[s][i] = 1;
g[i][s] = 0;
g[i + n][t] = 1;
g[t][i + n] = 0;
}
for (int i = 1, x, y; i <= m; i++) {
cin >> x >> y;
g[x][y + n] = 1;
g[y + n][x] = 0;
}
while (bfs()) {
while ((flow = dinic(s, INT_MAX)))
ans += flow;
}
for (int i = 1; i <= n; i++)
if (!d[i]) {
int x = i;
cout << x;
while (to[x] && to[x] != t) {
x = to[x] - n;
cout << ' ' << x;
}
cout << endl;
}
cout << n - ans << endl;
return 0;
}