信息学奥赛一本通T1394:最小生成树 连接格点

【题目描述】有一个M行N列的点阵,相邻两点可以相连。一条纵向的连线花费一个单位,一条横向的连线花费两个单位。某些点之间已经有连线了,试问至少还需要花费多少个单位才能使所有的点全部连通。【输入】第一行输入两个正整数m和n。以下若干行每行四个正整数x1,y1,x2,y2,表示第x1行第y1列的点和第x2行第y2列的点已经有连线。输入保证|x1−x2|+|y1−y2|=1。【输出】输出使得连通所有点还需

信息学奥赛一本通T1394:连接格点

【题目描述】

有一个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;
}

 

信息学奥赛一本通T1394:最小生成树 连接格点 归属于 最小生成树,更多同类题解源程序见:最小生成树 和 连接格点

0 条评论

请先 登录 后评论
不写代码的码农
轩爸

0 篇文章

作家榜 »

  1. admin 2 文章
  2. 张芳 0 文章
  3. hanna 0 文章
  4. Jason 0 文章
  5. lixiaioqian 0 文章
  6. GeraldWrora 0 文章
  7. 董伟 0 文章
  8. 信奥达人 0 文章