T1394 连接格点(#Ⅲ- 4 - 5)

【题目描述】

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


【输入】

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

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

【输出】

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

【输入样例】

2 2
1 1 2 1

【输出样例】

3

【源程序】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 1000001
#define MOD 123
#define E 1e-6
using namespace std;
int father[N];
int Find(int x)
{
    if(father[x]==x)
        return x;
    return father[x]=Find(father[x]);
}
int Union(int x,int y)
{
    x=Find(x);
    y=Find(y);
    if(x!=y)
    {
        father[y]=x;
        return 1;
    }
    return 0;
}
int main()
{
    int m,n;
    cin>>m>>n;

    for(int i=1;i<=m*n;i++)
        father[i]=i;

    int x1,x2,y1,y2;
    while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2)==4)
        Union((x1-1)*n+y1,(x2-1)*n+y2);

    int sum=0;
    for(int j=1;j<=n;j++)//连竖线需要一个单位
        for(int i=1;i<m;i++)
            if(Union((i-1)*n+j,(i)*n+j))
                sum+=1;
    for(int i=1;i<=m;i++)//连横线需要两个单位
        for(int j=1;j<n;j++)
            if(Union((i-1)*n+j,(i-1)*n+j+1))
                sum+=2;

    printf("%d\n",sum);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u011815404/article/details/80863275