「网络流 24 题」最小路径覆盖

来源:互联网 发布:js 计算时间差多少秒 编辑:程序博客网 时间:2024/06/10 20:50

题目连接:https://loj.ac/problem/6002


题目描述

给定有向图 G=(V,E) G = (V, E) G=(V,E)。设 P P P 是 G G G 的一个简单路(顶点不相交)的集合。如果 V V V 中每个顶点恰好在 P P P 的一条路上,则称 P P P 是 G G G 的一个路径覆盖。P P P 中路径可以从 V V V 的任何一个顶点开始,长度也是任意的,特别地,可以为 0 0 0。G G G 的最小路径覆盖是 G G G 的所含路径条数最少的路径覆盖。

设计一个有效算法求一个有向无环图 G G G 的最小路径覆盖。
输入格式

第 1 1 1 行有 2 2 2 个正整数 n n n 和 m m m。n n n 是给定有向无环图 G G G 的顶点数,m m m 是 G G G 的边数。
接下来的 m m m 行,每行有 2 2 2 个正整数 u u u 和 v v v,表示一条有向边 (i,j) (i, j) (i,j)。
输出格式

从第 1 1 1 行开始,每行输出一条路径。
文件的最后一行是最少路径数。
样例
样例输入

11 12
1 2
1 3
1 4
2 5
3 6
4 7
5 8
6 9
7 10
8 11
9 11
10 11

样例输出

1 4 7 10 11
2 5 8
3 6 9
3

数据范围与提示

1≤n≤200,1≤m≤6000 1 \leq n \leq 200, 1 \leq m \leq 6000 1≤n≤200,1≤m≤6000

算法竞赛入门经典训练指南 p357

#include <iostream>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>const int maxn = 500;typedef long long ll;using namespace std;int n,m;vector<int>G[maxn+5];int match[maxn+5];bool used[maxn+5];void Addedge(int fr,int to){    G[fr].push_back(to);}bool dfs(int v){    used[v] = true;    for(int i=0,l=G[v].size(); i<l; i++)    {        int u = G[v][i], w = match[u];        if(w<0||(!used[w]&&dfs(w)))        {            match[v] = u, match[u] = v;            return true;        }    }    return false;}int bip(){    int res = 0;    memset(match,-1,sizeof(match));    for(int v=1; v<=n; v++)    {        if(match[v]<0)        {            memset(used,0,sizeof(used));            if(dfs(v)) res++;        }    }    return res;}void DFS(int x){    if(match[x+n]!=-1) DFS(match[x+n]);    printf("%d ",x);}int main(){    int x,y;    while(~scanf("%d %d",&n,&m))    {        for(int i=1; i<=n+n; i++) G[i].clear();        for(int i=1;i<=m;i++)        {            scanf("%d %d",&x,&y);            Addedge(x,y+n);        }        int ans = n - bip();        for(int i=1;i<=n;i++)        {            if(match[i]!=-1) continue;            DFS(i);            printf("\n");        }        printf("%d\n",ans);    }    return 0;}


阅读全文
0 0
原创粉丝点击