Bipartite graph matching entry title

Board (Hungary algorithm, adjacency matrix)

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

The meaning of problems: FIG gives a given space and the separator 'X', seeking to place up to meet the conditions Blockhouse, conditions '.': If not, then separated by partitions, a house can only be placed on the vertical and horizontal directions , separators, then, after the partition of (relative position) is not considered.

Solution: separately for each row and each column is reduced in points (relabeling), even if the intersection of two sides (in fact, the two conditions link (row, column) to together)

#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

 

Guess you like

Origin www.cnblogs.com/Yokel062/p/11330059.html