zoukankan      html  css  js  c++  java
  • UVA-11419 SAM I AM (最小点覆盖)

    题目大意:在一个n*m的网格中,有k个目标,现在可以任选一行或列消除在其上的所有目标,求出最少选择次数及选法。

    题目分析:经典的最小点覆盖问题,并且输出一个最小点覆盖集。在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后x中未标记的和y中标记的点构成最小点覆盖集。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define REP(i,s,n) for(int i=s;i<n;++i)
    # define CL(a,b) memset(a,b,sizeof(a))
    # define CLL(a,b,n) fill(a,a+n,b)
    
    const int N=1005;
    struct Edge
    {
        int to,nxt;
    };
    Edge e[N*N];
    int link[N],visx[N],visy[N],vis[2*N],mark[N];
    int cnt,n,m,head[N];
    
    void add(int u,int v)
    {
        e[cnt].to=v;
        e[cnt].nxt=head[u];
        head[u]=cnt++;
    }
    
    void dfs1(int x)
    {
        visx[x]=1;
        for(int i=head[x];i!=-1;i=e[i].nxt){
            int y=e[i].to;
            if(visy[y]) continue;
            visy[y]=1;
            dfs1(link[y]);
        }
    }
    
    bool dfs(int x)
    {
        for(int i=head[x];i!=-1;i=e[i].nxt){
            int y=e[i].to;
            if(vis[y]) continue;
            vis[y]=1;
            if(link[y]==-1||dfs(link[y])){
                link[y]=x;
                return true;
            }
        }
        return false;
    }
    
    int match()
    {
        int res=0;
        REP(i,1,n+1){
            CL(vis,0);
            if(dfs(i)) ++res;
        }
        return res;
    }
    
    int main()
    {
        int a,b,k;
        while(scanf("%d%d%d",&n,&m,&k)&&(n+m+k))
        {
            cnt=0;
            CL(head,-1);
            CL(link,-1);
            CL(mark,0);
            CL(visx,0);
            CL(visy,0);
            while(k--)
            {
                scanf("%d%d",&a,&b);
                add(a,b);
            }
            int ans=match();
            REP(i,1,m+1) if(link[i]!=-1) mark[link[i]]=1;
            REP(i,1,n+1) if(!mark[i]) dfs1(i);
            printf("%d",ans);
            REP(i,1,n+1) if(!visx[i]) printf(" r%d",i);
            REP(i,1,m+1) if(visy[i]) printf(" c%d",i);
            printf("
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    Unity3D Resources TextAsset 正文
    使用位操作
    Chapter 3 Protecting the Data(3):创建和使用数据库角色
    找呀志_ContentResolver操作ContentProvider数据
    c#委托实例化和调用语句
    有意练习--Rails RESTful(一)
    对于晚辈:阅读经典“乱搭”形成了自己的“制”
    Eclipse SDK构建J2EE开发环境
    7.oracle学习门户系列七---网络管理和配置
    netback于kthread遇到cpu affinity问题
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4941063.html
Copyright © 2011-2022 走看看