【最大生成树】洛谷P2700 逐个击破

P2700 逐个击破

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 2e5 + 10, M = N;

int n, k;
LL res, sum;
bool st[N];
int p[N];

struct Edge
{
	int a, b, w;
	bool operator< (const Edge &t)const
	{
		return w > t.w;//从大到小排
	}
}e[M];

int find(int x)
{
	return x == p[x] ? x : p[x] = find(p[x]);
}

LL kruskal()
{
	for (int i = 1; i <= n; i++) p[i] = i;
	sort(e, e + n - 1);
	LL res = 0;
	for (int i = 0; i < n - 1; i++)
	{
		int a = find(e[i].a), b = find(e[i].b), w = e[i].w;
		if (a != b)
		{
			if (st[a] && st[b]) continue; //两个敌方结点
			p[a] = b;
			res += w;	
			if (st[a]) st[b] = true;
			else if (st[b]) st[a] = true;
		}
	}
	return res;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	
	cin >> n >> k;
	while (k--)
	{
		int x;
		cin >> x;
		st[x] = true;
	}
	for (int i = 0; i < n - 1; i++)
	{
		int a, b, w;
		cin >> a >> b >> w;
		e[i] = {a, b, w};
		sum += w;
	}
	printf("%lld", sum - kruskal());
	return 0;
}
posted @ 2025-01-18 15:14  Tshaxz  阅读(19)  评论(0)    收藏  举报
Language: HTML