标签:nbsp int nod 连接 i++ ++ pre out 贪心
题意:n个点(x,y) n<=1e5,在(a,b)-(c,d)连边cost为min(|a-c|,|b-d|),任意两个点连通的最小代价?
对于两点A,B 连接两条边 权值为|a-c|,|b-d|
按x坐标排序 A,B,C三点 由于要求MST,多点联通时只可能用到相邻点的边,A-C的边不可能在MST中
所以最多2(n-1)条边,跑MST即可.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+20;
const ll mod=1e9+7;
struct node{
ll x,y,id;
}a[N];
struct edge{
ll u,v,w;
}e[N];
bool cmp1(node a,node b)
{
return a.x<b.x;
}
bool cmp2(node a,node b)
{
return a.y<b.y;
}
bool cmp(edge a,edge b)
{
return a.w<b.w;
}
int fa[N];
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main()
{
int n;
while(cin>>n)
{
for(int i=1;i<=n;i++)
scanf("%I64d%I64d",&a[i].x,&a[i].y),fa[i]=i,a[i].id=i;
sort(a+1,a+1+n,cmp1);
int cnt=0;
for(int i=2;i<=n;i++)
e[cnt].u=a[i].id,e[cnt].v=a[i-1].id,e[cnt++].w=abs(a[i].x-a[i-1].x);
sort(a+1,a+1+n,cmp2);
for(int i=2;i<=n;i++)
e[cnt].u=a[i].id,e[cnt].v=a[i-1].id,e[cnt++].w=abs(a[i].y-a[i-1].y);
sort(e,e+cnt,cmp);
int num=n;
ll ans=0;
for(int i=0;i<cnt;i++)
{
int u=e[i].u,v=e[i].v;
int fx=find(u),fy=find(v);
if(fx!=fy)
{
ans+=e[i].w;
fa[fx]=fy;
num--;
if(num==1)
break;
}
}
cout<<ans<<endl;
}
return 0;
}
标签:nbsp int nod 连接 i++ ++ pre out 贪心
原文地址:http://www.cnblogs.com/HIKARI1149/p/7074623.html