1394:连接格点(grid)

【题目描述】

有一个M行N列的点阵,相邻两点可以相连。一条纵向的连线花费一个单位,一条横向的连线花费两个单位。某些点之间已经有连线了,试问至少还需要花费多少个单位才能使所有的点全部连通。

【输入】

第一行输入两个正整数m和n。

以下若干行每行四个正整数x1,y1,x2,y2x1,y1,x2,y2,表示第x1x1行第y1y1列的点和第x2x2行第y2y2列的点已经有连线。输入保证|x1−x2|+|y1−y2|=1|x1−x2|+|y1−y2|=1。

【输出】

输出使得连通所有点还需要的最小花费。

【输入样例】

2 2
1 1 2 1

【输出样例】

3

【提示】

【数据规模】

30%数据:n*m≤1000

100%数据:m,n≤1000

这题很有意思的一题,就是把坐标换成一个数,然后用并查集来做,这样就转换成我们平常做的类型,比较简单

还有一个问题,刚用vs不久,和我熟悉的codeblocks有点区别对于:ctrl+z在vs里是用ctrl+Y
ac代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e6+10;
int n, m;
int p[N];
int findth(int x)
{
	if (x == p[x]) return x;
	return p[x] = findth(p[x]);
}

int unionn(int x, int y)
{
	int xx = findth(x);
	int yy = findth(y);
	if (xx != yy) {
		p[yy] = xx;
		return 1;

	}
	return 0;
}
int main()
{
	scanf("%d %d", &n, &m);
	for (int i = 1;i <= n * m;i++) p[i] = i;
	int x1, y1, x2, y2;
	while (scanf("%d %d %d %d", &x1, &y1, &x2, &y2) == 4) {
		unionn((x1 - 1)*m + y1, (x2 - 1)*m + y2);
	}
	int sum = 0;
	for (int i = 1;i <= m;i++) {
		for (int j = 1;j < n;j++) {
			if (unionn((j - 1)*m + i, j*m + i))
				sum++;
		}
	}

	for (int i = 1;i <= n;i++) {
		for (int j = 1;j < m;j++) {
			if (unionn((i - 1)*m + j, (i - 1)*m + j + 1) ) sum += 2;
		}
	}
	printf("%d\n", sum);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Wchenchen0/article/details/81565828