逐个击破(并查集)

Posted SSL_LKJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逐个击破(并查集)相关的知识,希望对你有一定的参考价值。

逐个击破

在这里插入图片描述

解题思路

公路看作
城市看作
占领的城市称为特殊点
这题就成了
求使特殊点互不连通的最优删边方案

AC代码

#include<algorithm>
#include<cstdio>
using namespace std;
long long n,m,k,x,ans,b[1000005],f[1000005];
struct node
{
	long long x,y,z;
}a[1000005];
bool cmp(node x,node y)
{
	return x.z>y.z;
}
long long find(long long x)
{
	if(f[x]==x)return x;
	return f[x]=find(f[x]);
}
int main()
{
	scanf("%lld%lld%lld",&n,&m,&k);
	for(long long i=1;i<=n;i++)f[i]=i;//初值
	for(long long i=1,x;i<=k;i++)scanf("%lld",&x),b[x+1]=1;//初值
	for(long long i=1;i<=m;i++)
	{
		scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z);
		a[i].x++;a[i].y++;
		ans+=a[i].z;
	}
	sort(a+1,a+m+1,cmp);
	for(long long i=1;i<=m;i++)//核心
	{
		long long xx=find(a[i].x),yy=find(a[i].y);
		if(xx==yy)ans-=a[i].z;
		else if(!b[xx]||!b[yy])
		{
			ans-=a[i].z;
			if(b[yy])f[xx]=yy;
			else f[yy]=xx;
		}
	}
	printf("%lld",ans);
	return 0;
}

谢谢

以上是关于逐个击破(并查集)的主要内容,如果未能解决你的问题,请参考以下文章

LuoguP2700逐个击破并查集/生成树/正难则反By cellur925

p2700 逐个击破

P2700 逐个击破

L2-025 分而治之(并查集)

洛谷P2700 逐个击破

luoguP2700 逐个击破