HDU 1198——并查集

#include <bits/stdc++.h>
using namespace std;
bool type[11][4] = {{1, 1, 0, 0}, {0, 1, 1, 0}, {1, 0, 0, 1}, {0, 0, 1, 1}, {0, 1, 0, 1}, {1, 0, 1, 0}, {1, 1, 1, 0}, {1, 1, 0, 1}, {1, 0, 1, 1}, {0, 1, 1, 1}, {1, 1, 1, 1}};
int *pre, cnt, M, N;
const int MAX_N = 50;
char inp[MAX_N][MAX_N];
void init(int nm)
{
	pre = new int[nm];
	for (int i = 0; i < nm; i++)
		pre[i] = i;
	cnt = nm;
}
int find(int x)
{
	if (x != pre[x])
		pre[x] = find(pre[x]);
	return pre[x];
}
void merge(int i, int j)
{
	int self = inp[i][j] - 'A';
	int preself = find(i * N + j);
	if (i + 1 < M)
	{
		int test = inp[i + 1][j] - 'A';
		int pretest = find((i + 1) * N + j);//*N(N是每行有的个数)!!
		if (type[self][3] && type[test][1] && preself != pretest)
			pre[pretest] = preself, --cnt;

	}
	if (j + 1 < N)
	{
		int test = inp[i][j + 1] - 'A';
		int pretest = find(i * N + j + 1);
		if (type[self][2] && type[test][0] && preself != pretest)
			pre[pretest] = preself, --cnt;
	}
}
int main(int argc, char const *argv[])
{
	while (cin >> M >> N && M > 0 && N > 0)
	{
		for (int i = 0; i < M; i++)
			cin >> inp[i];
		init(N * M);
		for (int i = 0; i < M; i++)
			for (int j = 0; j < N; j++)
				merge(i, j);
		delete[] pre;
		cout << cnt << endl;
	}
	return 0;
}

做过的题,还错,持续re 5次,这就是不做注释的后果

用bool数组保存表示可联通的道路,显得简洁;

可以使用位运算

你可能感兴趣的:(HDU 1198——并查集)