HDU 1281 棋盘游戏

来源:互联网 发布:php彩票门户网站源码 编辑:程序博客网 时间:2024/05/18 17:57

棋盘游戏

带记忆化的求最大二分匹配。横坐标为一个集合的点,纵坐标为一个集合,棋盘上的点是二分图的边,最大匹配数是最多放的棋子数,最后还要求出这个位置是否为关键位置,只要先记住最优解棋子的所有位置,然后去掉一个棋子,再求最大匹配。比较先后值,统计关键子数。

#include<cstdio>#include<cstring>#include<algorithm>#define N 102using namespace std;bool map[N][N],vis[N];int link[N];int n,m;bool dfs(int i){    int j,k;    for(j=1; j<=m; j++)    {        if(map[i][j]&&!vis[j])        {            vis[j]=1;            k=link[j];            link[j]=i;            if(k==-1)                return 1;            if(dfs(k))                return 1;            link[j]=k;        }    }    return 0;}int maxpp(){    int sum=0,i;    for(i=1; i<=n; i++)    {        memset(vis,0,sizeof(vis));        if(dfs(i))            sum++;    }    return sum;}int main(){    int i,j,k,l;    int sum=0;    int imp[N][2];    int e=0;    while(~scanf("%d%d%d",&n,&m,&k))    {        e++;        memset(map,0,sizeof(map));        for(i=0; i<k; i++)        {            scanf("%d%d",&j,&l);            map[j][l]=1;        }        sum=0;        memset(link,-1,sizeof(link));        sum=maxpp();        l=0;        for(j=1;j<=m;j++)        {            if(link[j]!=-1)            {                l++;                imp[l][0]=link[j];                imp[l][1]=j;            }        }        int c=0;        for(i=1;i<=l;i++)        {            map[imp[i][0]][imp[i][1]]=0;            memset(link,-1,sizeof(link));            if(maxpp()!=sum)            c++;            map[imp[i][0]][imp[i][1]]=1;        }        printf("Board %d have %d important blanks for %d chessmen.\n",e,c,sum);    }    return 0;}





0 0
原创粉丝点击