首页 > 其他 > 详细

二分图匹配入门题

时间:2019-08-10 01:33:55      阅读:124      评论:0      收藏:0      [点我收藏+]

板子(匈牙利算法,邻接矩阵)

技术分享图片
const int MAXN=2e3+5;
int uN, vN;
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];

bool dfs(int u)
{
    for(int v=0; v<vN; v++)
        if(g[u][v] && !used[v])
        {
            used[v]=true;
            if(linker[v]==-1 || dfs(linker[v]))
            {
                linker[v]=u;
                return true;
            }
        }
    return false;
}

int hungary()
{
    int res=0;
    memset(linker, -1, sizeof(linker));
    for(int u=0; u<uN; u++)
    {
        memset(used, 0, sizeof(used));
        if(dfs(u)) res++;
    }
    return res;
}
View Code

 

HDU 1045

题意:给出一张图,给出空地‘.‘和隔板‘x’, 求放置最多满足条件的blockhouse,条件:垂直和水平方向上没有如果隔板隔开的话,只能放置一个house,有隔板话,隔板的之后(相对位置)的不用考虑。

题解:分别对每一行和每一列进行缩点(重新标号),两个相交的话就连边(其实就是把2个条件链接(行,列)到了一起)

技术分享图片
#include <bits/stdc++.h>
using namespace std; 
#define _for(i,a,b) for(int i=(a); i< (b); i++)
#define _rep(i,a,b) for(int i=(a); i<=(b); i++)

const int MAXN=2e2+5;
int uN, vN;
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];

bool dfs(int u)
{
    for(int v=0; v<vN; v++)
        if(g[u][v] && !used[v])
        {
            used[v]=true;
            if(linker[v]==-1 || dfs(linker[v]))
            {
                linker[v]=u;
                return true;
            }
        }
    return false;
}

int hungary()
{
    int res=0;
    memset(linker, -1, sizeof(linker));
    for(int u=0; u<uN; u++)
    {
        memset(used, 0, sizeof(used));
        if(dfs(u)) res++;
    }
    return res;
}

char Map[MAXN][MAXN];
int Mrow[MAXN][MAXN], Mcol[MAXN][MAXN];

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    //freopen("in.txt", "r", stdin);    
    int n;
    while(cin>>n, n)
    {
        _for(i, 0, n) _for(j, 0, n) cin>>Map[i][j];
        uN=vN=0;
        int cu=0, cv=0;
        memset(Mrow, -1, sizeof(Mrow));
        memset(Mcol, -1, sizeof(Mcol));
        _for(i, 0, n) _for(j, 0, n)
        {
            if(Mrow[i][j]==-1 && Map[i][j]==.)
            {
                for(int k=j; k<n&&Map[i][k]==.; k++)
                    Mrow[i][k]=cu;
                uN=max(uN, ++cu);
            }
            if(Mcol[i][j]==-1 && Map[i][j]==.)
            {
                for(int k=i; k<n&&Map[k][j]==.; k++)
                    Mcol[k][j]=cv;
                vN=max(vN, ++cv);
            }    
        }
        memset(g, 0, sizeof(g));
        _for(i, 0, n) _for(j, 0, n)
            if(Map[i][j]==.) g[Mrow[i][j]][Mcol[i][j]]=1;
        cout<<hungary()<<endl;
    }
    return 0;
}
View Code

 

二分图匹配入门题

原文:https://www.cnblogs.com/Yokel062/p/11330059.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!