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;
    }
  • 相关阅读:
    实例之内存体系结构(1)--- 共享池(Share pool)
    体系结构 --- 实例和数据库
    分页查询与TOP-N特性
    MERGE 和 WITH语法
    外部表
    SQL语句(9)--- 同义词
    SQL语句(8)--- 索引
    SQL语句(7)--- 视图
    SQL语句(6)--- 约束
    死锁的产生与解决
  • 原文地址:https://www.cnblogs.com/Narh/p/8868489.html
Copyright © 2011-2022 走看看