zoukankan      html  css  js  c++  java
  • AcWing——2549. 估计人数(最小重复路径点覆盖)

    原题链接

    思路:

    最小路径点覆盖
    DAG :用最少的互不相交的路径将所有点覆盖
    拆点:i ==> i出点 i'入点
    将原图里的每条路径 转化到新图里
    1.路径 匹配
    2.路径终点 左部非匹配

    让左侧非匹配点最多 <=>左侧匹配点最多 <=>找最大匹配

    最小路径重复点覆盖:用最少的路径将所有点覆盖
    1.求g传递闭包g'
    2.g的最小路径重复点覆盖==g'的最小路径覆盖

    代码:

    int s[30][30],n,m,mp[30][30],idx;
    int g[210][210];
    bool st[maxn];
    int mat[maxn];
    
    bool Find(int x){
        for(int i=1;i<=idx;i++)
            if(g[x][i]&&!st[i]){
                st[i]=1;
                int t=mat[i];
                if(t==0||Find(t)){
                    mat[i]=x;
                    return 1;
                }
            }
        return 0;
    }
    int main() {
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++)
    	        scanf("%1d",&s[i][j]);
    	for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++)
    	        if(s[i][j]==1) mp[i][j]=++idx;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                if(s[i][j]==1){
                    if(i+1<=n&&s[i+1][j]==1) g[mp[i][j]][mp[i+1][j]]=1;
                    if(j+1<=m&&s[i][j+1]==1) g[mp[i][j]][mp[i][j+1]]=1;
                }
            }
        for(int k=1;k<=idx;k++)
            for(int i=1;i<=idx;i++)  
                for(int j=1;j<=idx;j++)
                    if(g[i][k]&&g[k][j]) g[i][j]=1;
        int res=0;
        for(int i=1;i<=idx;i++){
            memset(st,0,sizeof st);
            if(Find(i)) res++;
        }
    
        cout<<idx-res<<endl;
    	return 0;
    }
    
    
  • 相关阅读:
    进程与线程的区别
    信号列表详解
    同步与互斥
    互斥锁
    读写锁
    Redis QPS测试
    从分布式锁来看redis和zookpeer!
    JVM虚拟机调参
    log4j.properties配置详解与实例
    生产者消费者(消费者要消费完才能退出)
  • 原文地址:https://www.cnblogs.com/OvOq/p/14751132.html
Copyright © 2011-2022 走看看