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;
    }
    
    
  • 相关阅读:
    时域和频域
    Python实用笔记 (26)面向对象高级编程——定制类
    Python实用笔记 (25)面向对象高级编程——多重继承
    去重-pd.duplicated
    合并pd.merge
    拼接
    pandas读取txt、excel、csv
    pandas字符串操作
    常用数据编辑-相加对齐
    成员判断
  • 原文地址:https://www.cnblogs.com/OvOq/p/14751132.html
Copyright © 2011-2022 走看看