AT_keyence2019_e Connecting Cities 题解

题目传送门

前置知识

Boruvka 算法

解法

考虑 Boruvka 算法。

拆掉绝对值后得到 \(a_{i}+id,a_{i}-id,a_{j}+id,a_{j}-id\) 四个式子。

vector 启发式合并辅助线段树查询的常数过大,无法通过。上述做法的常数在于一条边会被计算两次,考虑优化。

不妨直接钦定向前连、向后连的贡献,顺次扫的过程中是容易维护的。做法正确性由最优解一定包含与其中可以保证。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
ll a[200010],b[200010],c[200010],f[200010];
pair<ll,ll>g[200010];
multiset<pair<ll,ll> >s;
struct DSU
{
	ll fa[200010];
	void init(ll n)
	{
		for(ll i=1;i<=n;i++)
		{
			fa[i]=i;
		}
	}
	ll find(ll x)
	{
		return fa[x]==x?x:fa[x]=find(fa[x]);
	}
	void merge(ll x,ll y)
	{
		x=find(x);
		y=find(y);
		if(x!=y)
		{
			fa[x]=y;
		}
	}
}D;
ll boruvka(ll n)
{
	D.init(n);
	ll ans=0,flag=1,x;
	while(flag==1)
	{
		flag=0;
		fill(g+1,g+1+n,make_pair(0,0x3f3f3f3f3f3f3f3f));
		s.clear();
		for(ll i=1;i<=n;i++)
		{
			f[i]=0x3f3f3f3f3f3f3f3f;
			s.insert(make_pair(f[i],i));
		}
		for(ll i=1;i<=n;i++)
		{
			x=D.find(i);
			s.erase(make_pair(f[x],x));
			if(s.empty()==0&&s.begin()->first+c[i]<g[x].second)
			{
				g[x].first=s.begin()->second;
				g[x].second=s.begin()->first+c[i];
			}
			f[x]=min(f[x],b[i]);
			s.insert(make_pair(f[x],x));
		}
		s.clear();
		for(ll i=1;i<=n;i++)
		{
			f[i]=0x3f3f3f3f3f3f3f3f;
			s.insert(make_pair(f[i],i));
		}
		for(ll i=n;i>=1;i--)
		{
			x=D.find(i);
			s.erase(make_pair(f[x],x));
			if(s.empty()==0&&s.begin()->first+b[i]<g[x].second)
			{
				g[x].first=s.begin()->second;
				g[x].second=s.begin()->first+b[i];
			}
			f[x]=min(f[x],c[i]);
			s.insert(make_pair(f[x],x));
		}
		for(ll i=1;i<=n;i++)
		{
			x=D.find(i);
			if(g[x].first!=0&&D.find(x)!=D.find(g[x].first))
			{
				D.merge(x,g[x].first);
				ans+=g[x].second;
				flag=1;
			}
		}
	}
	return ans;
}
int main()
{
// #define Isaac
#ifdef Isaac
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	ll n,d,i;
	cin>>n>>d;
	for(i=1;i<=n;i++)
	{
		cin>>a[i];
		b[i]=a[i]-i*d;
		c[i]=a[i]+i*d;
	}
	cout<<boruvka(n)<<endl;
	return 0;
}
posted @ 2024-12-23 11:20  hzoi_Shadow  阅读(9)  评论(0编辑  收藏  举报
扩大
缩小