zoukankan      html  css  js  c++  java
  • cogs 728. [网络流24题] 最小路径覆盖问题 匈牙利算法

    728. [网络流24题] 最小路径覆盖问题

    ★★★☆   输入文件:path3.in   输出文件:path3.out   评测插件
    时间限制:1 s   内存限制:128 MB

    算法实现题8-3 最小路径覆盖问题(习题8-13)

    ´问题描述:

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

    提示:

    设V={1,2,...  ,n},构造网络G1=(V1,E1)如下:

    每条边的容量均为1。求网络G1的(x0,y0)最大流。

    ´编程任务:

    对于给定的给定有向无环图G,编程找出G的一个最小路径覆盖。

    ´数据输入:

    由文件input.txt提供输入数据。文件第1行有2个正整数n和m。n是给定有向无环图
    G的顶点数,m是G的边数。接下来的m行,每行有2个正整数i 和j,表示一条有向边(i,j)。

    ´结果输出:

    程序运行结束时,将最小路径覆盖输出到文件output.txt中。从第1行开始,每行输出

    一条路径。文件的最后一行是最少路径数。

    输入文件示例

    input.txt 
    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

     输出文件示例

    output.txt

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

     

     

    讲解:

    Coding!

    发现自己还是太弱了

    这样一道看起来比较简单的二分图最小路径覆盖问题都能出问题 唉

    现在我们来讲一下这一道题的易错点

    1.最小路径覆盖数是  节点数n  -   二分图的最大匹配数

    2.这一道题让输出路径  那么这应该怎么办呢?

    我想了一个办法是这个样子的

    首先我们在累加那个ans的时候枚举节点跑匈牙利算法dfs的时候不是从小往大枚举的吗

    也就是说那个hav数组 在正常的情况下是hav[后]=hav[前]  但是 如果是这个样子 我们不好输出路径 因为我比较想去从头(较小的)开始输出

    那么我们再来看一个son数组 和hav数组正好是反过来的

    同时我们再设一个in数组 来存储入度

    所以经过了上面的处理

    我们只需要枚举n个点 如果这个点的入度为0   那么我们就从这个点开始  顺着son往后跑 就能打印出该条路径啦

    具体内容看代码理解咯(其实还是比较 简单的  我啰嗦了那么多   还是看代码比较清晰一点啦)

    鸿篇巨制:

    #include<bits/stdc++.h>
    #define maxn 205
    using namespace std;
    int n,m;
    int vis[maxn],hav[maxn],tim=0;
    vector<int> v[maxn];
    int in[maxn];
    int son[maxn];
    bool Dfs(int x)
    {
        for(int i=0;i<v[x].size();i++)
        {
            int y=v[x][i];
            if(vis[y]!=tim)
            {
                vis[y]=tim;
                if(!hav[y]||Dfs(hav[y]))
                {
                    hav[y]=x;
                    son[x]=y;
                    in[y]++;
                    return true;
                }
            }
        }
        return false;
    }
    bool Printed[maxn];
    void Print(int i)
    {
        int x=i;
        while(x!=0)
        {
            printf("%d ",x);
            Printed[x]=true;
            x=son[x];
        }
        putchar('
    ');
    }
    int main()
    {
        freopen("path3.in","r",stdin);
        freopen("path3.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            tim++;
            ans+=Dfs(i);
        }
        for(int i=1;i<=n;i++)
            if(in[i]==0)
                Print(i);
        printf("%d
    ",n-ans);
        return 0;
    }

    点个赞 加个关注再走呗

  • 相关阅读:
    C#开发模式——单例模式
    C#开发模式——单例模式
    Memcached的基础梳理
    Memcached的基础梳理
    Memcached的基础梳理
    Memcached的基础梳理
    13条只有程序员才能懂的内涵段子
    13条只有程序员才能懂的内涵段子
    网页性能优化
    webpack中使用ECharts
  • 原文地址:https://www.cnblogs.com/Tidoblogs/p/11408305.html
Copyright © 2011-2022 走看看