棋盘游戏 杭电 1281

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1281

输入:先输入棋盘大小,然后输入K个可以放“車”的点(可容点)。

输出:第cnt个数据,“重要点”个数,可以放几个“車”。

“重要点”:去掉Map[i][j]点后放置“車”的数量会减少,那么这个点为重要点,否则不是重要点。

思路:先算出能放置的最大“車”数ans;

           对每个可容点遍历,将可容点变成不可容点,再计算可放置“車”数answer(),如果可放置“車”数少了,即(answer()<ans),那么这点自然就是重要点了(num++)。

AC代码:

#include<iostream>
#include<cstring>
using namespace std;
bool Map[123][123],vis[123];
int Link[123],M,N;
bool Find(int x)
{
	for(int i=1;i<=N;i++)
	{
		if(!vis[i]&&Map[x][i])
		{
			vis[i]=1;
			if(!Link[i]||Find(Link[i]))
			{
				Link[i]=x;
				return 1;
			}
		}
	}
	return 0;
}
int answer()
{
	int ans=0;
	for(int i=0;i<=M;i++)
		{
			memset(vis,0,sizeof(vis));
			if(Find(i)) ans++; 
		}
	return ans;
}
int main()
{
	int cnt=0;
	int K;
	while(cin>>M>>N>>K)
	{
		memset(Map,0,sizeof(Map));
		memset(Link,0,sizeof(Link));
		while(K--)
		{
			int a,b;
			cin>>a>>b;
			Map[a][b]=1;
		}
		int ans=answer();
		int num=0;
		for(int i=1;i<=M;i++)
		{
			for(int j=1;j<=N;j++) 
			{
				if(Map[i][j])
				{
					memset(Link,0,sizeof(Link)); //每次都要重新定义链接线
					Map[i][j]=0;
					if(answer()<ans) num++;
					Map[i][j]=1; 
				}
			}
		} 
		printf("Board %d have %d important blanks for %d chessmen.\n",++cnt,num,ans);
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jack_jxnu/article/details/81197673
今日推荐