• POJ 2594 Treasure Exploration(Floyd+最小路径覆盖)


    题意:求有向图的最小路径覆盖,但是点可以被多条路径重复走过!

    求最小路径覆盖的问题:HDU1151, 链接: http://acm.hdu.edu.cn/showproblem.php?pid=1151

    分析:点能被重复覆盖是和单纯地求最小路径覆盖的区别,这样的话在一个弱连通子图中,可能出现中间结点已经被走过,但是之后的点没被覆盖的情况,这时匹配的结果就会比原来大。

    那么可以通过求出图的传递闭包来加边,将原来没有直接边的点建立关系,这样就能得到正确结果。

    #include<iostream>
    #include<stdio.h>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define Lson rt<<1,l,m
    #define Rson rt<<1|1,m+1,r
    using namespace std;
    typedef long long LL;
    const int maxn = 1e3+5,maxm = 2e5+5;
    int N;
    struct Edge{
        int to,next;
    }edges[maxm];
    int head[maxn],tot;
    int linker[maxn];
    bool used[maxn];
    
    void init()
    {
        tot=0;
        memset(head,-1,sizeof(head));
    }
    
    void AddEdge(int u,int v)
    {
        edges[tot].to = v;
        edges[tot].next = head[u];
        head[u] = tot++;
    }
    
    bool dfs(int u){
        int v,st,ed;
        for(int i=head[u];~i;i = edges[i].next){
            v = edges[i].to;
            if(!used[v]){
                used[v]=true;
                if(linker[v]==-1||dfs(linker[v])){
                    linker[v]=u;
                    return true;
                }
            }
        }
        return false;
    }
    
    int hungary(){
        int res=0;
        memset(linker,-1,sizeof(linker));
        for(int u=1;u<=N;u++){
            memset(used,0,sizeof(used));
            if(dfs(u)) res++;
        }
        return res; 
    }
    
    void Floyd()
    {
        for(int u=1;u<=N;++u){
            for(int i = head[u];~i;i =edges[i].next){
                int v=edges[i].to;
                for(int j=head[v];~j;j=edges[j].next){
                    AddEdge(u,edges[j].to);
                }
            }
        }
    }
    
    void debug()
    {
        
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int T,M,u,v,tmp,k;
        while(scanf("%d%d",&N,&M)==2){
            if(!N) break;
            init();
            for(int i=1;i<=M;++i){
                scanf("%d%d",&u,&v);
                AddEdge(u,v);
            }
            Floyd();      
            printf("%d
    ",N-hungary());
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    POJ 1990 MooFest
    python的unittest測试框架的扩展浅谈
    星云測试- Android应用深度体检专业平台
    HDOJ 1507 Uncle Tom&#39;s Inherited Land*
    产品设计
    Linux网络编程--wireshark分析TCP包头的格式
    java读取中文分词工具(一)
    为datatable添加自增列
    Oracle 自己主动内存管理 SGA、PGA 具体解释
    TCP/IP基础
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9373840.html
Copyright © 2020-2023  润新知