HDU 4185

http://acm.hdu.edu.cn/showproblem.php?pid=4185

两个挨着的'#'可以配成一对,求最多能配成几对

挨着的'#'就连边,然后求一次最大匹配,答案是最大匹配除以二(因为1 2和2 1这两对匹配实际效果是1,但是会算成2)

#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std ;

struct node{

    int s,t,nxt ; 

}e[500005] ;

int m,n,head[500005],cnt,match[500005],vis[500005] ;

int find(int s)

{

    for(int i=head[s] ;i!=-1 ;i=e[i].nxt)

    {

        int tt=e[i].t ;

        if(!vis[tt])

        {

            vis[tt]=1 ;

            if(match[tt]==-1 || find(match[tt]))

            {

                match[tt]=s ;

                return 1 ;

            }

        }

    }

    return 0 ;

}

int max_match()

{

    int ans=0 ;

    memset(match,-1,sizeof(match)) ;

    for(int i=1 ;i<=m ;i++)

    {

        memset(vis,0,sizeof(vis)) ;

        ans+=find(i);

    }

    return ans;

}

void add(int s,int t) {e[cnt].s=s ;e[cnt].t=t ;e[cnt].nxt=head[s] ;head[s]=cnt++ ;}

char M[605][605] ;

int mp[605][605] ;

int dx[]={1,-1,0,0} ;

int dy[]={0,0,1,-1} ;

int main()

{

    int T ;

    scanf("%d",&T) ;

    for(int cas=1 ;cas<=T ;cas++)

    {

        int N ;

        scanf("%d",&N) ;

        for(int i=0 ;i<N ;i++)

            scanf("%s",M[i]) ;

        n=0 ;

        memset(mp,0,sizeof(mp)) ;

        for(int i=0 ;i<N ;i++)

        {

            for(int j=0 ;j<N ;j++)

            {

                if(M[i][j]=='#')

                {

                    n++ ;

                    mp[i][j]=n ;

                }

            }

        }

        memset(head,-1,sizeof(head)) ;

        cnt=0 ;

        for(int i=0 ;i<N ;i++)

        {

            for(int j=0 ;j<N ;j++)

            {

                if(M[i][j]=='#')

                {

                    for(int k=0 ;k<4 ;k++)

                    {

                        int xx=i+dx[k] ;

                        int yy=j+dy[k] ;

                        if(xx<0 || xx>=N || yy<0 || yy>=N)continue ;

                        if(mp[xx][yy])

                        {

                            add(mp[i][j],mp[xx][yy]) ;

                        }

                    }

                }

            }

        }

        m=n ;

        printf("Case %d: %d\n",cas,max_match()/2) ;

    }

    return 0 ;

}
View Code

你可能感兴趣的:(HDU)