求图中独立子图个数
Floodfill漫水填充法,也称种子填充法,在图形学中有很多应用。像Windows下的“画图”软件的油漆桶工具就是基于这个算法的。要给某个密闭区域涂色或者更改某个密闭区域内的颜色时,程序自动选中与种子点(鼠标左键单击的地方)周围相同颜色的区域,接着将该区域替换成指定的颜色。
模型:
将地图抽象为二维矩阵,图中的数字表示海拔,0表示海拔,1~9表示陆地。将图中的某个点为源点对其临点进行着色。用深度优先遍历,将地图上的每一个大于0的点都进行一遍,从最开始开始一直枚举到(n,m)对每个点进行尝试染色。
示例代码:
#include <stdio.h>
#include <stdlib.h>
int a[51][51],book[51][51];
int n,m,sum;
void dfs(int x,int y,int color)
{
//定义方向数组
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int k,tx,ty;
a[x][y]=color; //对这个格子进行染色
//四个方向进行尝试
for(k=0;k<=3;k++)
{
//下一步的坐标
tx=x+next[k][0];
ty=y+next[k][1];
//判断是否越界
if(tx<1||tx>n||ty<1||ty>m)
continue;
//判断是否为陆地
if(a[tx][ty]>0&&book[tx][ty]==0)
{
sum++;
book[tx][ty]=1;
dfs(tx,ty,color);
}
}
return;
}
int main(void)
{
int i,j,num=0;
printf("Please input the grid's col and row divided by one space:\n");
//读入地图大小n为行,m为列
scanf("%d %d",&n,&m);
//读入地图
printf("The grid contains space represented by over 0 and water represented by 0.\n");
printf("Please input the grid divided by one space:\n");
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
//对每一个大于0的点尝试进行dfs染色
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(a[i][j]>0)
{
num--;
book[i][j]=1;
dfs(i,j,num);
}
}
}
//输出染色后的地图
printf("The grid signed.\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
printf("%3d",a[i][j]);
printf("\n");
}
printf("There are %d space.",-num);
return 0;
}
这其实在图中求一个图中独立子图的个数,取一个结点,对其标记,然后标记它所有的邻结点。对它的每一个邻结点这么一直递归下去完成搜索。
实例结果: