Codevs 1904 最小路径覆盖问题

1904 最小路径覆盖问题
时间限制: 2 s
空间限制: 256000 KB
题目等级 : 大师 Master
传送门
题目描述 Description
给定有向图G=(V,E)。设P 是G 的一个简单路(顶点不相交)的集合。如果V 中每个
顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖。P 中路径可以从V 的任何一个顶
点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少
的路径覆盖。
设计一个有效算法求一个有向无环图G 的最小路径覆盖。
对于给定的给定有向无环图G,编程找出G的一个最小路径覆盖。
输入描述 Input Description
第1 行有2个正整数n和m。n是给定有向无环图
G 的顶点数,m是G 的边数。接下来的m行,每行有2 个正整数i和j,表示一条有向边(i,j)。
输出描述 Output Description
将最小路径覆盖输出。从第1 行开始,每行输出
一条路径。文件的最后一行是最少路径数。
样例输入 Sample Input
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
样例输出 Sample Output
1 4 7 10 11
2 5 8
3 6 9
3
数据范围及提示 Data Size & Hint
分类标签 Tags
网络流 图论

/*
匈牙利算法.
二分图匹配.
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#define MAXN 2001
using namespace std;
vector<int>g[MAXN];
int x[MAXN],y[MAXN],n,m,tot;
bool b[MAXN];
bool dfs(int u)
{
    for(int i=0;i<g[u].size();i++)//扩展连接点 
    {
        int v=g[u][i];
        if(!b[v])
        {
            b[v]=true;
            if(!y[v]||dfs(y[v]))
            {
                y[v]=u;//记录前驱 
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int x,y;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
      {
        cin>>x>>y;
        g[x].push_back(y);
      }
    for(int i=1;i<=n;i++)
    {
        memset(b,0,sizeof(b));
        if(dfs(i)) tot++;//最大匹配基数 
      }  
    cout<<n-tot;
    return 0;  
}
posted @ 2016-07-09 16:57  nancheng58  阅读(134)  评论(0编辑  收藏  举报