POJ 3041 二分图匹配入门题

Description

给出一个N*N的矩阵,其中有K个障碍,每次可以选择删去某一整行或者一整列障碍,求最少的删去障碍次数。

Input

第一行N和K

之后K行每行给出一个障碍的行列坐标。

Ouput

一行,一个整数表示最少次数。

Analysis

目标是把矩阵中的障碍物全部删去。有两个主体,一个是矩阵,另一个是障碍物。

首先站在矩阵的角度考虑。考虑行和列,把一行删去的话可能可以同时删去几个障碍,列也同样。然而,前一次的删去会对之后造成影响,状态就是整个矩阵,用贪心和动态规划都不合适。

换个角度,考虑每个障碍物。每个障碍物都要删去,必然是通过它的行或者列删去的,每个障碍物所连得行或列都至少要占据一个。这里就有了很强的图论背景了,每个障碍物是边,行和列分别是点,则整个图构成了一个二分图,问题就是求至少用多少个点能占据每条边至少一端。这也就是二分图最小覆盖问题。可以证明二分图最小覆盖=二分图最大匹配。直接用匈牙利算法即可。

扫描二维码关注公众号,回复: 874570 查看本文章

这是二分图匹配入门题,顺便再概括性的说一说匈牙利算法,实际上是,每次对一个节点u求匹配,能找到就选上。考虑每个u所能连得点v,如果当前与v所连的点能够找到别的替代(这里找新的代替就是个递归过程),则让v与替代相连,而让u与v相连,造成一个两全其美的局面,如此反复下去。更多的关于匈牙利算法,觉得这篇博客讲得很好,挺有意思。https://blog.csdn.net/dark_scope/article/details/8880547

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.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)
typedef long long LL;
int readint() { int x; cin >> x; return x; }
const int INF = 1 << 30;
const int maxn = 505;

vector<int>G[maxn];
int n,m;
int used[maxn],match[maxn];
bool find(int u){
    for(int i=0;i<G[u].size();++i){
        int v=G[u][i];
        if(!used[v]){
            used[v]=1;
            if(match[v]==0||find(match[v])){
                match[v]=u;
                return true;
            }
        }
    }
    return false;
}

int main()
{

	//freopen("C:\\Users\\admin\\Desktop\\in.txt", "r", stdin);
	//freopen("C:\\Users\\admin\\Desktop\\out.txt", "w", stdout);
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=n;++i)G[i].clear();
        for(int i=0;i<m;++i){
            int u,v;scanf("%d%d",&u,&v);
            G[u].push_back(v);
        }

        memset(match,0,sizeof(match));
        int ans=0;
        for(int i=1;i<=n;++i){
            memset(used,0,sizeof(used));
            if(find(i)) ans++;
        }
        printf("%d\n",ans);
    }

	return 0;
}

猜你喜欢

转载自blog.csdn.net/tomandjake_/article/details/80272713