您的位置:首页 > 其它

棋盘游戏---hdu1281(最大匹配)

2015-08-10 17:38 232 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281

题目大意:就是车和车之间不能发生攻击.还有一部分位置不可以放置棋子。

解题思路:一行一列只能放一个,那么对于横纵坐标x和y来说一行一列只有一个交点。所以我们就可以根据X坐标与Y坐标把这些点转换为二分图。

对于重要点问题,我们就可以把这个点去掉,涂黑不让他走,然后在进行一次二分匹配,如果发现最大匹配值小了,那么这个就是重要点。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 110

int maps

, vis
, used
, n, m, k, ans, ans0;
struct node
{
int x,y;
}a[N*N];///注意k的取值范围,wa了一次;
bool Find(int u)
{
for(int i=1; i<=m; i++)
{
if(!vis[i] && maps[u][i])
{
vis[i] = 1;
if(!used[i] || Find(used[i]))
{
used[i] = u;
return true;
}
}
}
return false;
}

int main()
{
int t = 1, x, y;
while(scanf("%d%d%d", &n, &m, &k)!=EOF)
{
ans = ans0 = 0;
memset(used, 0, sizeof(used));
memset(maps, 0, sizeof(maps));
for(int i=1; i<=k; i++)
{
scanf("%d%d", &x, &y);
a[i].x = x;
a[i].y = y;
maps[x][y] = 1;
}
for(int i=1; i<=n; i++)
{
memset(vis, 0, sizeof(vis));
if(Find(i))
ans++;
}
for(int i=1; i<=k; i++)
{
int kk=0;
memset(used, 0, sizeof(used));
x=a[i].x;
y=a[i].y;
maps[x][y] = 0;
for(int j=1; j<=n; j++)
{
memset(vis, 0, sizeof(vis));
if(Find(j))
kk++;
}
if(kk<ans)
ans0++;
maps[x][y] = 1;
}
printf("Board %d have %d important blanks for %d chessmen.\n", t++, ans0, ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: