HDU-1281-棋盘游戏 [二分匹配][关键匹配]

来源:互联网 发布:麦迪62分数据 编辑:程序博客网 时间:2024/05/18 18:43

题目传送门


题意:给定二分图求最大匹配数和关键匹配数。

思路:先通过匈牙利算法求最大匹配数,然后遍历二分图,去掉一条边之后再用匈牙利算法算匹配数,如果小于最大匹配数,则这个边为关键点。

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>using namespace std;int m,n,k;int path[110][110];bool used[110];int match[110];bool Dfs(int x){    for (int i = 1; i <= m; i++)    {        if (!used[i] && path[x][i])        {            used[i] = true;            if (!match[i] || Dfs(match[i]))            {                match[i] = x;                return true;            }        }    }    return false;}int Matching(){    int ans = 0;    memset(match, 0, sizeof(match));    for (int i = 1; i <= n; i++)    {        memset(used, false, sizeof(used));        if (Dfs(i))        {            ans++;        }    }    return ans;}int main(void){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int t = 1;    while (~scanf("%d %d %d", &n, &m, &k))    {        memset(path,0,sizeof(path));        for (int i = 0; i < k; i++)        {            int x, y;            scanf("%d %d", &x, &y);            path[x][y] = 1;        }        int ans = Matching();        int count = 0;        for (int i = 1; i <= n; i++)        {            for (int j = 1; j <= m; j++)            {                if (path[i][j])                {                    path[i][j]=false;                    int tmp = Matching();                    path[i][j] = true;                    if (tmp < ans)                        count++;                }            }        }        printf("Board %d have %d important blanks for %d chessmen.\n", t++, count, ans);    }    return 0;}
原创粉丝点击