1394:連接格點(grid)
時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2798 通過數: 967
【題目描述】
有一個M行N列的點陣,相鄰兩點可以相連。一條縱向的連線花費一個單位,一條橫向的連線花費兩個單位。某些點之間已經有連線了,試問至少還需要花費多少個單位才能使所有的點全部連通。
【輸入】
第一行輸入兩個正整數m和n。
以下若干行每行四個正整數x1,y1,x2,y2,表示第x1行第y1列的點和第x2行第y2列的點已經有連線。輸入保證|x1−x2|+|y1−y2|=1。
【輸出】
輸出使得連通所有點還需要的最小花費。
【輸入樣例】
2 2
1 1 2 1
【輸出樣例】
3
【提示】
【數據規模】
30%數據:n×m≤1000;
100%數據:m,n≤1000。
思路:把座標轉換成數,然後用並查集來做,連豎線需要一個單位,連橫線需要兩個單位。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1E6+10;
int n,m;
int p[N];
int find(int x){
if(x == p[x]) return x;
return p[x] = find(p[x]);
}
int un(int x,int y){
int xx = find(x);
int yy = find(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){
un((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(un((j - 1)*m + i, j*m + i))//第j行第i個,第j+1行第i個
sum++;
}
}
for (int i = 1;i <= n;i++) {
for (int j = 1;j < m;j++) {
if (un((i - 1)*m + j, (i - 1)*m + j + 1) ) sum += 2;//第i行第j個,第i行第j+1個,連起來
}
}
printf("%d\n", sum);
return 0;
}