POJ 3020アンテナの配置の最大の一致

アンテナの配置
制限時間: 1000ミリ秒   メモリの制限: 65536kも
合計の提出: 6445   受け入れ: 3182

説明

グローバル空中研究センターは、スウェーデンの携帯電話のネットの第五世代を構築する作業を割り当てられてきました。彼らは仕事を得た理由で最も印象的な理由は、新しい、非常にノイズ耐性、アンテナの発見です。それは4DAirと呼ばれ、4種類入って来ています。各タイプだけのため地球の相互作用する電磁場の、(やや斜め)緯度と経度グリッドに整列方向に信号を送信及び受信することができます。4つのタイプがそれぞれ、北、西、南、東方向に動作するアンテナに対応します。以下は、それらをカバーする楕円で示されている12個の小さなリング、および9つの4DAirアンテナによって描か興味のある場所、の例の画像です。

もちろん、可能な限り少数のアンテナを使用しますが、それでも興味のある場所ごとにカバレッジを提供することが望ましいです。我々は、次のような問題をモデル化する:Aのエントリがいずれかの少なくとも1つのアンテナ、または空の空間によって覆われなければならない関心のある点、であるスウェーデンの表面を記述する矩形行列であるとします。アンテナは、行r及び列cにあるときのアンテナのみA.内のエントリに配置することができ、このエントリは(C、R + 1、被覆考えだけでなく、隣接するエントリ(C + 1、R)の一つであります)、(C-1、R)、または(c、R-1)は、この特定のアンテナのために選択された種類に応じて覆われています。関心のあるすべてのポイントがカバーされるように配置が存在するため、アンテナの最小数は何ですか?



入力

入力の最初の行に従うシナリオの数を指定する、単一の正の整数nです。<= 10は、その後、H線の形でスウェーデンの関心のあるポイントを記述する、提示行列wは各シナリオは、<1 <=さh <= 40を有する2つの正の整数、HおよびWを含む行で始まり、0各セット[ '*'、 'O']から文字wを含みます。「*」 - 「O'-文字はオープンスペースを表し、一方、文字は、注目点を象徴しています。

出力

独自の行に、シナリオのマトリクス内のエントリ - 各シナリオのために、出力は、必要なアンテナの最小数は、すべての「*」をカバーします。

サンプル入力

2 
7 9 
OOOのOOOO ** 
** OOOのOO * 
又は* YES **または** 
ooooooooo 
OO ******* 
O * O * OO OO 
はい******* 
10 1 
* 
* 
* 
または
* 
* 
* 
* 
* 
*

サンプル出力

17 
5


最小パス二部グラフの頂点にありませんカバレッジ= - マッチ/ 2の半分の最大数

#include<iostream>
#include<cstring>
using namespace std;

#define M 405
int a[M][M],b[M][M];
int p;
int v[M],f[M];
int w[4][2]={0,1,0,-1,1,0,-1,0};

int fi(int x)
{
	for(int i=1;i<=p;i++)
		if(!v[i] && b[x][i])
		{
			v[i]=1;
			if(!f[i] || fi(f[i]))
			{
				f[i]=x;
				return 1;
			}
		}
	return 0;
}

int main()
{
	int T;
	cin>>T;getchar();
	while(T--)
	{		
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(f,0,sizeof(f));
		int n,m;
		cin>>n>>m;
		int i,j;
		char c;

		p=0;
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=m;j++)
			{
				cin>>c;
				if(c=='*')
					a[i][j]=++p;
			}
			getchar();
		}

		for(i=1;i<=n;i++)
			for(j=1;j<=m;j++)
				if(a[i][j])   for(int q=0;q<4;q++)
				{
					int x=i+w[q][0];
					int y=j+w[q][1];
					if(a[x][y])
						b[a[i][j]][a[x][y]]=1;
				}

		int sum=0;
		for(i=1;i<=p;i++)
		{
			memset(v,0,sizeof(v));
			if(fi(i))   sum++;
		}
		
		cout<<p-sum/2<<endl;
	}

	return 0;
}


おすすめ

転載: www.cnblogs.com/mqxnongmin/p/10960669.html