zoukankan      html  css  js  c++  java
  • LUOGU P2764 最小路径覆盖问题 (最小路径点覆盖)

    解题思路

    有向图最小路径点覆盖问题,有这样的结论就是有向图最小路径点覆盖等于n-拆点二分图中最大匹配。具体怎么证明不太知道。。输出方案时找到所有左部未匹配的点一直走$match​$就行了。



    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    
    using namespace std;
    const int MAXN = 305;
    const int MAXM = 6005;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    
    int n,m,a[MAXN][MAXN],ans,match[MAXN],num,vis[MAXN],go[MAXM];
    bool suc[MAXN];
    
    bool dfs(int x){
        for(register int i=n+1;i<=2*n;i++)if(a[x][i]){
            if(vis[i]==num) continue;vis[i]=num;
            if(!match[i] || dfs(match[i])) {match[i]=x;return true;}
        }
        return false;
    }
    
    void out(int x){
        if(!x) return;
        out(x/10);
        putchar('0'+x%10);
    }
    
    int main(){
        n=rd(),m=rd();int x,y;
        for(register int i=1;i<=m;i++){
            x=rd(),y=rd();
            a[x][y+n]=1;
        }
        for(register int i=1;i<=n;i++)
            num++,ans+=dfs(i);
        ans=n-ans;
        for(register int i=n+1;i<=2*n;i++) suc[match[i]]=1;
        for(register int i=1;i<=n;i++)
            if(!suc[i]) {
                int cnt=0,now=i;
                while(now) {go[++cnt]=now;now=match[now+n];}
                for(register int j=cnt;j;j--) out(go[j]),putchar(' ');
                putchar('
    ');
            }
        cout<<ans<<endl;
        return 0;
    }
    View Code

     

  • 相关阅读:
    php+mysql 实现无限极分类
    php 开启微信公众号开发者模式
    PHP对象继承
    phpexcel导出数字带E的解决方法
    jquery layui的巨坑
    jquery jssdk分享报错解决方法
    javascript腾讯地图放到网页中的方法
    jquery手机端横屏判断方法
    javascript 字符串转化成函数执行
    PHP创建文件命名中文乱码解决的方法
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9754761.html
Copyright © 2011-2022 走看看