您的位置:首页 > 理论基础 > 计算机网络

【二分匹配】 [网络流24题] 最小路径覆盖问题

2015-08-10 10:47 671 查看
网络流24题中的经典题目。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int maxn = 305;
const int maxm = 20005;

struct Edge
{
int v;
Edge *next;
}E[maxm], *H[maxn], *edges;
int res[maxn];
int vis[maxn];

void addedges(int u, int v)
{
edges->v = v;
edges->next = H[u];
H[u] = edges++;
}

void init()
{
edges = E;
memset(H, 0, sizeof H);
memset(res, -1, sizeof res);
}

bool find(int u)
{
for(Edge *e = H[u]; e; e = e->next) if(!vis[e->v]) {
int v = e->v;
vis[v] = 1;
if(res[v] == -1 || find(res[v])) {
res[v] = u;
return true;
}
}
return false;
}

int n, m;
vector<int> ans;
int to[maxn];

void work()
{
int u, v;
for(int i = 1; i <= m; i++) {
scanf("%d%d", &u, &v);
addedges(u, v);
}

int result = 0;
for(int i = 1; i <= n; i++) {
memset(vis, 0, sizeof vis);
if(find(i)) result++;
}

memset(to, 0, sizeof to);
for(int i = 1; i <= n; i++) if(res[i] != -1) to[res[i]] = i;

for(int i = 1; i <= n; i++) if(res[i] == -1) {
ans.clear();
int u = i;
ans.push_back(u);
while(to[u]) {
u = to[u];
ans.push_back(u);
}
for(int j = 0; j < ans.size(); j++) printf("%d%c", ans[j], j == ans.size() - 1 ? '\n' : ' ');
}

printf("%d\n", n - result);
}

int main()
{
freopen("path3.in", "r", stdin);
freopen("path3.out", "w", stdout);
while(scanf("%d%d", &n, &m) != EOF) {
init();
work();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: