传送门:连接格点
思路:每一个坐标都化成一个点,距离为2的横向边和距离为1的纵向的边都存入一个数组,最后做一遍最小生成树就行了
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1000002;
int n,m;
int f[N];
struct nod
{
int x,y,w;
}node[4000010];
bool cmp(nod a,nod b)
{
return a.w<b.w;
}
int find(int x)
{
if(x!=f[x])
f[x]=find(f[x]);
return f[x];
}
int a1,b1,c1,d1;
int main()
{
scanf("%d%d",&n,&m);
int idx=1;
int p=n*m;
for(int i=1;i<=p;i++)
f[i]=i;
while(scanf("%d%d%d%d",&a1,&b1,&c1,&d1)!=EOF)
{
//break;
int x=(a1-1)*m+b1;
int y=(c1-1)*m+d1;
node[idx++]={x,y,0};
// break;
}
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++)
{
int x=(i-1)*m+j;
int y=x+1;
node[idx++]={x,y,2};
}
for(int i=1;i<=m;i++)
for(int j=1;j<n;j++)
{
int x=(j-1)*m+i;
int y=x+m;
node[idx++]={x,y,1};
}
sort(node+1,node+idx,cmp);
int ans=0;
for(int i=1;i<=idx;i++)
{
int a=node[i].x,b=node[i].y,c=node[i].w;
a=find(a),b=find(b);
if(a!=b)
{
// cout<<c<<endl;
ans+=c;
f[b]=a;
}
}
cout<<ans<<endl;
return 0;
}