用DFS求连通块进阶
Posted wanshe-li
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用DFS求连通块进阶相关的知识,希望对你有一定的参考价值。
UVA-1103(Ancient Messages,World Finals)
点击看图
输入H行W列的字符矩阵(H<=200, W<=50)
每个字符都是16进制数字,将他们转化为二进制后产生的图形中有‘1‘和‘0‘,构成上面的图形。
根据符号内部白色洞的数量来判断。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <vector>
#include <set>
using namespace std;
const int MAXH = 210;
const int MAXW = 100;
int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};
char* bin[]= {"0000","0001","0010","0011","0100","0101","0110","0111",
"1000","1001","1010","1011","1100","1101","1110","1111"};
char code[] = "WAKJSD";
int W,H;
char pic1[MAXH][MAXW];
char pic[MAXH][MAXW<<2];
int color[MAXH][MAXW<<2];
void dfs(int x, int y, int col)
{
color[x][y] = col;
for(int i = 0; i < 4; ++i){
int xx = x + dx[i], yy = y + dy[i];
if(xx >= 0 && xx < H && yy >= 0 && yy < W
&& pic[x][y] == pic[xx][yy] && !color[xx][yy]){
dfs(xx,yy,col);
}
}
}
int main(void)
{
//freopen("input.txt","r",stdin);
int cas = 1;
while(scanf("%d %d", &H, &W), H || W){
memset(pic,0,sizeof(pic));
memset(color,0,sizeof(color));
for(int i = 0; i < H; ++i)
scanf("%s",pic1[i]);
for(int i = 0 ; i < H; ++i){
for(int j = 0; j < W; ++j){
if(isdigit(pic1[i][j]))
pic1[i][j] -= ‘0‘;
else
pic1[i][j] -= ‘a‘ - 10;
for(int k = 0; k < 4; ++k)
pic[i+1][1 + 4 * j + k] = bin[pic1[i][j]][k] - ‘0‘;
}
}
H += 2;
W = 4 * W + 2;
int cnt = 0;
vector<int> cc;
for(int i = 0; i < H; ++i){
for(int j = 0; j < W; ++j){
if(!color[i][j]){
dfs(i,j,++cnt);
if(pic[i][j] == 1) cc.push_back(cnt);
}
}
}
vector<set<int> > neigh(cnt+1);
for(int i = 0; i < H; ++i){
for(int j = 0; j < W; ++j){
if(pic[i][j]){
for(int k = 0; k < 4; ++k){
int x = i + dx[k], y = j + dy[k];
if(x >= 0 && x < H && y >= 0 && y < W &&
pic[x][y] == 0 && color[x][y] != 1)
neigh[color[i][j]].insert(color[x][y]);
}
}
}
}
vector<char> ans;
for(int i = 0, sz = cc.size(); i < sz; ++i)
ans.push_back(code[neigh[cc[i]].size()]);
sort(ans.begin(),ans.end());
printf("Case %d: ",cas++);
for(int i = 0, sz = ans.size(); i < sz; ++i)
printf("%c",ans[i]);
puts("");
}
return 0;
}
以上是关于用DFS求连通块进阶的主要内容,如果未能解决你的问题,请参考以下文章
UVA 572 -- Oil Deposits(DFS求连通块+种子填充算法)