最大匹配

HDU 1498 50 years, 50 colors

尽管是大水题 但是再怎么说就是自己走过的路啊
不过现在只是二分图入门阶段 到现在为止接触的一些题目真的是太水了 只要 吧题目理解 套个模板就好了 所以这里就只拿一个hdu1498作为水题典例

简单说 题目是个最小点覆盖问题 二分图的最小点覆盖==最大匹配数 问的是哪些数字在k步操作内无法完全覆盖 也就是说最大匹配大于k的有哪些

AC Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <iterator>

using namespace std;
const int maxn=105;
int n,k;
int g[maxn][maxn],link[maxn];
bool vis[maxn];
set<int> kao;
int hungary(int);
bool dfs(int,int);

int main()
{
    int temp,ans[maxn];
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        if(n==0&&k==0) break;
        kao.clear();
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                scanf("%d",&temp);
                kao.insert(temp);
                g[i][j]=temp;
            }
        int num=0,kase=0;
        for(set<int>::iterator it=kao.begin(); it!=kao.end(); it++)
        {
            temp=hungary(*it);
            if(temp>k) ans[num++]=*it;
        }
        if(num==0) printf("-1");
        else
        {
            sort(ans,ans+num);
            for(int i=0; i<num; i++)
            {
                if(kase++) putchar(' ');
                printf("%d",ans[i]);
            }
        }
        puts("");
    }
    return 0;
}
int hungary(int key)
{
    int num=0;
    for(int i=1; i<=n; i++) link[i]=-1;
    memset(link,-1,sizeof link);
    for(int i=1; i<=n; i++)
    {
        memset(vis,false,sizeof vis);
        if(dfs(i,key)) num++;
    }
    return num;
}

bool dfs(int x,int key)
{
    for(int i=1; i<=n; i++)
        if(!vis[i]&&g[x][i]==key)
        {
            vis[i]=true;
            if(link[i]==-1||dfs(link[i],key))
            {
                link[i]=x;
                return true;
            }
        }
    return false;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注