其实可能是因为知道是用并查集做的原因啦,一下就看出题意了,明显是并查集思想,每次输入地图中的一块,检测这一块与它顶头的那块可不可以相通
如果可以合并集合;同理检测其与它左边的那一块;最后遍历一遍看有多少个根结点即要多少个水源
下面是代码,有点乱
#include<iostream>
#include<vector>
#define M 55
#define N 55
using namespace std;
class elem{
public:
bool up;
bool down;
bool right;
bool left;
};
class cor{
public:
int x;
int y;
};
cor father[M][N];
int n,m;
void init(vector<elem>& farm){//初始化给出的11块地的样子保存下来,下标为0的不要
elem x;
x.up = false;
x.down = false;
x.right = false;
x.left = false;
farm.push_back(x);//0
x.up = true;
x.down = false;
x.right = false;
x.left = true;
farm.push_back(x);//1
x.up = true;
x.down = false;
x.right = true;
x.left = false;
farm.push_back(x);//2
x.up = false;
x.down = true;
x.right = false;
x.left = true;
farm.push_back(x);//3
x.up = false;
x.down = true;
x.right = true;
x.left = false;
farm.push_back(x);//4
x.up = true;
x.down = true;
x.right = false;
x.left = false;
farm.push_back(x);//5
x.up = false;
x.down = false;
x.right = true;
x.left = true;
farm.push_back(x);//6
x.up = true;
x.down = false;
x.right = true;
x.left = true;
farm.push_back(x);//7
x.up = true;
x.down = true;
x.right = false;
x.left = true;
farm.push_back(x);//8
x.up = false;
x.down = true;
x.right = true;
x.left = true;
farm.push_back(x);//9
x.up = true;
x.down = true;
x.right = true;
x.left = false;
farm.push_back(x);//10
x.up = true;
x.down = true;
x.right = true;
x.left = true;
farm.push_back(x);//11
}
int change(char x){//索引
return x-'A'+1;
}
cor find_father(int x,int y){//找根结点
if(x == father[x][y].x && y == father[x][y].y){
cor root; root.x = x; root.y = y;
return root;
}
else{
father[x][y] = find_father(father[x][y].x,father[x][y].y);
}
return father[x][y];
}
void merge(cor a,cor b){合并
father[a.x][a.y] = b;
}
void process(int x,int y,elem map[M][N]){//两个方向的处理
int _x = x-1;
int _y = y;
if(_x >= 1 && _x <= n && _y >= 1 && _y <= m && map[x][y].up && map[_x][_y].down){//上下两个图都有pipe
cor a = find_father(x,y);
cor b = find_father(_x,_y);
if(!(a.x == b.x && a.y == b.y))
merge(a,b);
}
_x = x; _y = y-1;
if(_x >= 1 && _x <= n && _y >= 1 && _y <= m && map[x][y].left && map[_x][_y].right){//左右
cor a = find_father(x,y);
cor b = find_father(_x,_y);
if(!(a.x == b.x && a.y == b.y))
merge(a,b);
}
}
int main()
{
vector<elem> farm;//保存11个初始地图
elem map[M][N];
init(farm);
while(cin >>n >>m && (n > 0 && m > 0)){
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
father[i][j].x = i;
father[i][j].y = j;
}
}
for(int i = 1;i <= n;i++){
for(int j = 1; j <= m;j++){
char x;
cin >>x;
map[i][j] = farm[change(x)];
process(i,j,map);
}
}
int count = 0;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
if(i == father[i][j].x && father[i][j].y == j)
count++;
}
}
cout <<count <<endl;
}
return 0;
}
本文介绍了一种使用并查集数据结构解决特定地图上水源数量计算的问题。通过输入不同形状的土地,并根据土地间的连接关系进行集合合并,最终统计独立集合的数量即所需水源数。
2550

被折叠的 条评论
为什么被折叠?



