zoukankan      html  css  js  c++  java
  • hdu1045 二分匹配

    这题我是在总结过程中想找二分匹配做做的,如果是平时我估计就直接深搜了。。

    二分匹配一开始没想出来如何建图,开始的思路有点阻塞,后来突然就明白了。

    题意,给一个n*n的棋盘  图中有X和。其中X代表墙,问棋盘中最多能放多少个‘车’使每个车都安全。

    先对行搜索,一行中若隔一个X则相当于有2行,找出所有的行并标上序号,然后对列同样进行操作。这样二分图的两边的点就全找出来了。

    然后对于图中每一个‘。’号进行连边将L【i】【j】与R【i】【j】相连,求最大匹配即是答案。

    代码:

    #include<iostream>
    #include<cstring>
    const int MAXN = 100;
    using namespace std;
    struct g{
        int num;
        int boy[MAXN];
    }gr[MAXN];
    bool flag[MAXN];
    int pre[MAXN];
    int n,m;
    int DFS(int x)
    {
        for(int i=0;i<gr[x].num;i++)         //男生
        {
            if(!flag[gr[x].boy[i]])         //未被匹配
            {
                flag[gr[x].boy[i]]=true;
                if(pre[gr[x].boy[i]]==-1||DFS(pre[gr[x].boy[i]]))
                {
                    pre[gr[x].boy[i]]=x;      //第几个女生
                    return 1;
                }
            }
        }
        return 0;
    }
    char c[5][5];
    int r[5][5];
    int l[5][5];
    int main()
    {
        int sum,k,a,b;
        while(cin>>n&&n!=0)
        {
            for(int i=0;i<n;i++)
            {
                cin>>c[i];
            }
            //找行   标号
            int temp=1;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    if(c[i][j]=='X')
                    {temp++;r[i][j]=-1;}
                    else
                    r[i][j]=temp;
                    if(j==n-1)temp++;
                }
            }
            int rn=temp-1;
            //找列
            temp=1;
            for(int j=0;j<n;j++)
            {
                for(int i=0;i<n;i++)
                {
                    if(c[i][j]=='X')
                    {
                        temp++;l[i][j]=-1;
                    }
                    else
                        l[i][j]=temp;
                    if(i==n-1)temp++;
                }
            }
            int ln=temp-1;
            for(int i=0;i<=10;i++)
                gr[i].num=0;
            for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            {
                if(l[i][j]!=-1)
                {
                    gr[r[i][j]].boy[gr[r[i][j]].num++]=l[i][j];
                }
            }
            sum=0;
            memset(pre,-1,sizeof(pre));
            for(int i=1;i<=rn;i++)            //行
            {
                memset(flag,0,sizeof(flag));
                sum+=DFS(i);
            }
            cout<<sum<<endl;
    
        }
        return 0;
    }
    


     

  • 相关阅读:
    STL源代码剖析——STL算法之set集合算法
    iOS + Nodejs SSL/Https双向认证
    C语言将10进制转为2进制
    图的遍历算法
    Web—CSS概述
    苹果新的编程语言 Swift 语言进阶(八)--属性
    UVa 10700
    C++实现KMP模式匹配算法
    软件project
    oralce GROUPING SETS
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134141.html
Copyright © 2011-2022 走看看