HDU 1281 棋盘游戏-二分匹配

来源:互联网 发布:pc端护眼软件 编辑:程序博客网 时间:2024/04/30 21:31

在棋盘里放尽可能多的车,让他们不能互相攻击,有一些格子不能放车,但不影响他们互相攻击。问最多能放多少个车,并且求出有多少个重要点,重要点就是如果不在这个点上放车,就不能尽可能的多放棋子。

先求出最大匹配数,然后枚举去掉每一个格子,如果得到的匹配数小于最大匹配数,重要点就多一个。


#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn = 1550;int e[maxn][maxn],match[maxn],book[maxn];int n,m,k;struct node{    int x,y;}p[10010];int dfs(int u){    int i;    for(i=1;i<=m;i++)    {        if(book[i]==0 && e[u][i] == 1)        {            book[i] = 1;            if(match[i] ==0 || dfs(match[i]))            {                match[i] = u;                return 1;            }        }    }    return 0;}int solve(){    int sum = 0;    memset(match,0,sizeof(match));    for(int i=1;i<=n;i++)    {        memset(book,0,sizeof(book));        if(dfs(i))            sum++;    }    return sum;}int main(void){    int i,j,k,t1,t2;    int c = 1;    while(scanf("%d%d%d",&n,&m,&k)==3)    {        memset(e,0,sizeof(e));        for(i=0;i<k;i++)        {            scanf("%d%d",&t1,&t2);            e[t1][t2] = 1;            p[i].x = t1;            p[i].y = t2;        }        int ans = solve();        int cnt = 0;        for(i=0;i<k;i++)        {            e[p[i].x][p[i].y] = 0;            if(solve()<ans)                cnt++;            e[p[i].x][p[i].y] = 1;        }        printf("Board %d have %d important blanks for %d chessmen.\n",c++,cnt,ans);    }}


0 0