zoukankan      html  css  js  c++  java
  • POJ2226Muddy Fields

    题目:http://poj.org/problem?id=2226

    巧妙建图:以行或列上的联通块作为点,每个泥格子作为边,求最小点覆盖就可以了!

    于是用匈牙利算法找最大匹配。注意要对右部点记录每一个左部点的vis!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int n=55,N=((n*n)<<1);
    int r,c,head[N],xnt=1,stack[n],top,cnt,col[n][n],pre[N],knt;
    char ch[n][n];
    bool vis[N];
    struct Edge{
        int next,to;
        Edge(int n=0,int t=0,int c=0):next(n),to(t) {}
    }edge[N];
    bool check(int cur)
    {
        for(int i=head[cur],v;i;i=edge[i].next)
            if(!vis[v=edge[i].to])
            {
                vis[v]=1;
                if(!pre[v=edge[i].to]||check(pre[v]))
                {pre[v]=cur;/*printf("cur=%d v=%d
    ",cur,v);*/return true;}
            }
        return false;
    }
    void cz1(int i)
    {
        cnt++;
        while(ch[i][stack[top]]=='*')col[i][stack[top--]]=cnt;
    }
    void cz2(int i)
    {
        cnt++;
        while(ch[stack[top]][i]=='*')
        {
            edge[++xnt]=Edge(head[col[stack[top]][i]],cnt);
    //        printf("%d %d
    ",col[stack[top]][i],cnt);
            head[col[stack[top--]][i]]=xnt;
        }
    }
    int main()
    {
        scanf("%d%d",&r,&c);
        for(int i=1;i<=r;i++)
        {
            getchar();
            for(int j=1;j<=c;j++)
            {
                scanf("%c",&ch[i][j]);
                if(ch[i][j]=='*')stack[++top]=j;
                else if(top)cz1(i);
            }
            if(top)cz1(i);
            top=0;
        }
    //    for(int i=1;i<=r;i++)
    //    {
    //        for(int j=1;j<=c;j++)
    //            printf("%d",col[i][j]);printf("
    ");
    //    }
        int lm=cnt;
        for(int i=1;i<=c;i++)
        {
            for(int j=1;j<=r;j++)
            {
                if(ch[j][i]=='*')stack[++top]=j;
                else if(top)cz2(i);
            }
            if(top)cz2(i);
            top=0;
        }
        for(int i=1;i<=lm;i++)
        {
            memset(vis,0,sizeof vis);//万一同一次踩在同一个未匹配右部点的话 
            if(check(i))knt++;    //右边不会主动匹配左边 ,这个i一定未匹配 
        }
        printf("%d",knt);
        return 0;
    }
  • 相关阅读:
    Python 学习笔记 11.模块(Module)
    Python 学习笔记 8.引用(Reference)
    Python 学习笔记 9.函数(Function)
    Python 学习笔记 6.List和Tuple
    Python 学习笔记 4.if 表达式
    Python 学习笔记 2.自省
    Python 学习笔记 3.简单类型
    Python 学习笔记 7.Dictionary
    Python 学习笔记 5.对象驻留
    Python 学习笔记 10.类(Class)
  • 原文地址:https://www.cnblogs.com/Narh/p/8868489.html
Copyright © 2011-2022 走看看