码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4158

时间:2016-05-07 07:43:54      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:

第一次看到以为是连通块,结果后来才知道是二分匹配技术分享

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4185

通过这个题学习的匈牙利算法。

思路:1、将图输入,并把每个“#”标上序号;

    2、将能匹配的进行标记;

   3、进行匹配,找出结果;

代码如下:

#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
char a[605][605];
int mapp[605][605];
int pp[700];
int pp1[700];
int mark[605][605];
int vis[700];
int num;
int ans;
bool find_pp(int x)
{

    for(int j=1; j<=num; j++)
    {
        if(mapp[x][j]&&!vis[j])//如果想和j可以匹配而且j没有匹配
        {
            vis[j]=1;
            if(!pp[j]||find_pp(pp[j])==true)//如果没有匹配 或者 已经匹配了但是找到一个新的匹配,则进行匹配
            {
                pp[j]=x;把x匹配给j
                return true;
            }
        }
    }
    return false;
}

int main()
{
    int t;
    scanf("%d",&t);
    int cases=0;
    while(t--)
    {
        int ans=0;
        cases++;
        int n;
        num=1;
        memset(mapp,0,sizeof(mapp));
        memset(mark,0,sizeof(mark));
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%s",a[i]);
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
            {
                if(a[i][j]=='#')
                {
                    mark[i][j]=num;
                    num++;
                }
            }
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
            {
                if(a[i][j]=='#')
                {
                    if(j<n-1&&a[i][j+1]=='#')
                    {
                        mapp[mark[i][j+1]][mark[i][j]]=1;
                        mapp[mark[i][j]][mark[i][j+1]]=1;
                    }
                    if(i<n-1&&a[i+1][j]=='#')
                    {
                        mapp[mark[i][j]][mark[i+1][j]]=1;
                        mapp[mark[i+1][j]][mark[i][j]]=1;

                    }
                }
            }

        ans=0;
        memset(pp,0,sizeof(pp));
        for(int i=1; i<=num; i++)//对每个数字进行匹配
        {
            memset(vis,0,sizeof(vis));
            if(find_pp(i)==true)
                ans++;
        }
        printf("Case %d: %d\n",cases,ans/2);//因为是无向图,匹配了两遍,所以结果要除2;
    }
}



HDU 4158

标签:

原文地址:http://blog.csdn.net/thewaysofar/article/details/51332673

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!