【题目描述】
有一个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 篇文章
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!