题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198
读完题目的那一瞬间,我觉得这题就是道水题...
常规的并查集模板直接写吧~
不过这题我莫名的CE了两次,最后从结果来看,是rank数组报错...虽然在自己的电脑上跑没问题。
题目想明白就好了~这也没什么难的嘛~抠耳
以下是AC代码:
/*
name:Rollchuchy
type:并查集
*/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
#define MAX_N 55
using namespace std;
int par[MAX_N*MAX_N];
int Rank[MAX_N*MAX_N];
char maze[MAX_N][MAX_N];
int dx[4]={1,0,-1,0};
int dy[4]={0,-1,0,1};
//初始化n个值
void init(int n)
{
for(int i=1;i<=n;i++)
{
par[i]=i;
Rank[i]=0;
}
}
//查询树的根
int find(int x)
{
return x==par[x]?x:par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x==y) return ;
if(Rank[x]<Rank[y])
{
par[x]=y;
}
else
{
par[y]=x;
if(Rank[x]==Rank[y]) Rank[x]++;
}
}
//判断x和y是否属于同一集合
bool same(int x,int y)
{
return find(x)==find(y);
}
int main()
{
//freopen("in.txt","r",stdin);
int m,n;
while(cin>>m>>n)
{
if(m==-1&&n==-1) break;
init(m*n);
for(int i=0;i<m;i++)
cin>>maze[i];
//solve()
int sum=1;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
for(int k=0;k<4;k++)
{
int nx=i+dx[k];
int ny=j+dy[k];
if(nx<0||ny<0||nx>=m||ny>=n) continue;
char s=maze[i][j];
char ss=maze[nx][ny];
if(dx[k]==1)//↓-> ↓
{
if((s=='C'||s=='D'||s=='E'||s=='H'||s=='I'||s=='J'||s=='K')&&(ss=='A'||ss=='B'||ss=='E'||ss=='G'||ss=='H'||ss=='J'||ss=='K'))
{
unite(sum,sum+n);
}
}
else if(dx[k]==-1)//↑-> ↑
{
if((s=='A'||s=='B'||s=='E'||s=='G'||s=='H'||s=='J'||s=='K')&&(ss=='C'||ss=='D'||ss=='E'||ss=='H'||ss=='I'||ss=='J'||ss=='K'))
{
unite(sum,sum-n);
}
}
else if(dy[k]==1)//→-> →
{
if((s=='B'||s=='D'||s=='F'||s=='G'||s=='J'||s=='I'||s=='K')&&(ss=='A'||ss=='C'||ss=='F'||ss=='G'||ss=='H'||ss=='I'||ss=='K'))
{
unite(sum,sum+1);
}
}
else if(dy[k]==-1)//←-> ←
{
if((s=='A'||s=='C'||s=='F'||s=='G'||s=='H'||s=='I'||s=='K')&(ss=='B'||ss=='D'||ss=='F'||ss=='G'||ss=='I'||ss=='J'||ss=='K'))
{
unite(sum,sum-1);
}
}
}
sum++;
}
}
int ans=0;
map<int,int> CJ;
for(int i=1;i<=m*n;i++)
{
int SB=find(i);
if(!CJ[SB])
{
CJ[SB]=1;
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}