hdu 1281 棋盘游戏

来源:互联网 发布:淘宝优惠券不能用 编辑:程序博客网 时间:2024/06/15 21:18

原题:http://acm.hdu.edu.cn/showproblem.php?pid=1281

/*思路:二分图的最大匹配 要明白,同一行或同一列不能同时有两个 车,就是两个车的坐标x或y不能相同。  其实整个棋盘可以 看成一个矩阵,可以将其画成二分图------左边是x坐标,右边是y坐标 模拟这个过程:我们想尽全力在每一行都放一个车,即先从不同的x出发(这样就保证了行不一样),接着尽量让每一个x都找到未被使用的y(这样保证了列与其他的不一样),画成图就是让一个x连线到一个y,最多车能放的数目即为这个二分图的最大匹配ans 求出能放车的最大数目后,再依次去掉各个点,看是否会减少 ans,如果会,该店点就是重要点。 */ #include<stdio.h>#include<memory.h>int a[101][101];int used[101];int pair[101];int left[101*101];int right[101*101];int n,m,k;bool find(int x){for(int i=1;i<=m;i++){if(a[x][i]==1 && used[i]==0){used[i]=1;if(pair[i]==0 || find(pair[i])==true){pair[i]=x;return true;}}} return false;}int main(){int t=0;while(~scanf("%d %d %d",&n,&m,&k)){t++;memset(a,0,sizeof(a));memset(pair,0,sizeof(pair));for(int i=1;i<=k;i++){scanf("%d %d",&left[i],&right[i]);a[left[i]][right[i]]=1;}int ans=0;//最大匹配 int rs=0;//重要点 for(int i=1;i<=n;i++){memset(used,0,sizeof(used));if(find(i)){ans++;}}for(int i=1;i<=k;i++){memset(pair,0,sizeof(pair));//初始化,所有还没有配对 a[left[i]][right[i]]=0;int tmp=0; int j;for(j=1;j<=n;j++){memset(used,0,sizeof(used));if(find(j)){tmp++;}}a[left[i]][right[i]]=1;if(tmp<ans){rs++;}} printf("Board %d have %d important blanks for %d chessmen.\n",t,rs,ans);}return 0;}