C++ 并查集模板:找矩阵中'0'区域的个数

#include "time.h"
#include <vector>
#include <iostream>
#include <map>

using namespace std;

template <typename T>
class UnionFind {
private:
	map<T, T> parent;
public:
	void Union(T x, T y) {
		map<T, T>::iterator i;
		T px = Find(x);
		T py = Find(y);
		i = parent.find(px);
		if (i == parent.end()) return;
		if (px != py) {
			i->second = py;
		}
	}
	T Find(T x) {
		map<T, T>::iterator i;
		i = parent.find(x);
		if (i == parent.end()) {
			parent.insert(pair<T, T>(x, x));
			return x;
		}
		if (i->second != x)
			i->second = Find(i->second);
		return i->second;
	}
};

int GetId(int r, int c, int col)
{return r * col + c;}

int FindAreas(vector<vector<int>> &matrix)
{
	int cur;
	int count = 0;
	int row = matrix.size();
	int col = matrix[0].size();
	UnionFind<int> uf;
	for (int i = 0;i < row;++i) {
		for (int j = 0;j < col;++j) {
			if (!matrix[i][j]) {
				if (i && !matrix[i - 1][j])
					uf.Union(GetId(i, j, col), GetId(i - 1, j, col));
				if (j && !matrix[i][j - 1])
					uf.Union(GetId(i, j, col), GetId(i, j - 1, col));
				if (i < row - 1 && !matrix[i + 1][j])
					uf.Union(GetId(i, j, col), GetId(i + 1, j, col));
				if (j < col - 1 && !matrix[i][j + 1])
					uf.Union(GetId(i, j, col), GetId(i, j + 1, col));
				uf.Find(GetId(i, j, col));
			}
		}
	}
	for (int i = 0;i < row;++i) {
		for (int j = 0;j < col;++j) {
			if (!matrix[i][j]) {
				cur = uf.Find(GetId(i, j, col));
				if (cur >= 0) {
					count--;
					uf.Union(GetId(i, j, col), count);
				}
			}
		}
	}
	return count * -1;
}

int main(int argc, char **argv)
{
	int n;
	srand(time(0));
	while (1) {
		cout<<"SIZE:";
		cin>>n;
		cout<<endl;
		vector<vector<int>> m(n, vector<int>(n, 0));
		for (int i = 0;i < n;++i) {
			for (int j = 0;j < n;++j) {
				m[i][j] = rand() % 2;
				cout<<m[i][j];
			}
			cout<<endl;
		}
		cout<<"======================="<<endl;
		cout<<"NUMBER OF ZERO AREAS: "<<FindAreas(m)<<endl<<endl;
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值