ベニーは、潅漑する広々とした農地を持っています。農地は、長方形であり、samllの正方形のロットに分割されます。水道管は、これらの正方形に配置されています。別の広場には、パイプの異なる種類があります。図1に示すように、AからKにマークされている配管の11種類があります。
図1
ベニーは、ファーム全体にわたって水管の分布を表すマークの配列である彼の農場の地図を有しています。例えば、彼は、地図を持っている場合
ADC
FJK
IHE
その後、水道管が同様に分散されています
図2
水は別の正方形の管に沿って流れることができるように、いくつかの源泉は、いくつかの正方形の中心に見出されます。水の流れは、1平方を横切る場合は、この広場で全体の農地は灌漑で、秋の豊作を持っています。
今、ベニーは、全体の農地を灌漑有することが見出されるべき少なくともどのように多くの源泉知りたいです。あなたは彼を助けることはできますか?
注:上記の例では、少なくとも3つの源泉を、図2に示すのもの赤い点として、必要とされています。
入力
いくつかのテストケースがあります!各テストケースでは、最初の行は、その後、M行が続く、2つの整数M及びNを含んでいます。これらのラインの各々において、Nの文字は、対応する正方形上水管の種類を示す、「K」に「A」の範囲内に存在します。負MまたはNは他のあなたは、<1を仮定することができ、入力の終了を示し= M、N <= 50
の出力
各テストケースについて、1つのラインの出力に必要な源泉の最小数。
サンプル入力
2 2
DK
HF
3 3
ADC
FJK
IHE
-1 -1
サンプル出力
2
3
题意:给你一个N*M的矩阵,由下面11种格子组成,每个格子互联的部分不同(比如A如果放在
C正下面,那么A与C是连通的),问你所给矩阵一共有几个连通分量。
解析:先把图构造出来,一共有n*m个联通分量,若有一次有效合并 连通分量-1
注意:遍历四个方向要与每个图所写的方向要一致
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=1e5+100;
int fa[N];
int dx[4]={-1,1,0,0}; //这边的方向要与下面的一致
int dy[4]={0,0,-1,1};
//上下左右
int con[11][4]={{1,0,1,0},{1,0,0,1},{0,1,1,0},{0,1,0,1},{1,1,0,0},
{0,0,1,1},{1,0,1,1},{1,1,1,0},{0,1,1,1},{1,1,0,1},{1,1,1,1}};
int v[1005][1005];
int n,m;
char ch;
int find(int x)
{
if(x!=fa[x]) return fa[x]=find(fa[x]);
return fa[x];
}
int build(int a,int b)
{
int x=find(a);
int y=find(b);
if(x!=y)
{
fa[x]=y;
return 1;
}
return 0;
}
int main()
{
while(~scanf("%d %d",&n,&m)&&n!=-1&&m!=-1)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf(" %c",&ch);
//cout<<ch<<endl;
v[i][j]=ch-'A';
}
}
for(int i=0;i<=n*m;i++) fa[i]=i;
int sum=n*m;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
int id=i*m+j;
for(int k=0;k<4;k++)
{
int x=dx[k]+i;
int y=dy[k]+j;
int dir=(k%2==0) ? k+1: k-1;
if(x>=0&&x<n&&y>=0&&y<m)
{
int did=x*m+y;
if(con[v[i][j]][k]==1&&con[v[x][y]][dir]==1)
{
sum-=build(id,did);
}
}
}
}
}
cout<<sum<<endl;
}
}