77分求助
查看原帖
77分求助
986886
TangHaohong楼主2024/3/24 12:10
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
	return x * f;
}
struct A {
	int x, y, l;
} edge[300010];
struct E {
	int to, l;
};
vector<E> tree[100010];
int n, m, father[100010], deep[100010], jump[1000010][20], fir[300010][20], sec[300010][20], sum;
bool used[300010];
int find(int x) {
	return x == father[x] ? x : father[x] = find(father[x]);
}
void finddep(int now) {
	for (int i = 0; i < tree[now].size(); i++) {
		int to = tree[now][i].to;
		if (to != jump[now][0]) {
			jump[to][0] = now;
			deep[to] = deep[now] + 1;
			fir[to][0] = tree[now][i].l;
			sec[to][0] = LONG_LONG_MIN;
			//	cout<<"to:"<<to<<endl;
			finddep(to);
		}
	}
}
void init() {
	for (int i = 1; i <= 20; i++)
		for (int j = 1; j <= n; j++) {
			int f = jump[j][i - 1];
			jump[j][i] = jump[f][i - 1];
			int t[4] = {fir[j][i - 1], sec[j][i - 1], fir[f][i - 1], sec[f][i - 1]};
			sort(t, t + 4);
			fir[j][i] = t[3];
			if (t[3] == t[2])
				sec[j][i] = t[1];
			else
				sec[j][i] = t[2];
		}
}
int lca(int x, int y) {
	if (deep[x] < deep[y]) swap(x, y);
	for (int i = 20; i >= 0; i--)
		if (deep[jump[x][i]] >= deep[y])
			x = jump[x][i];
	if (x == y)
		return x;
	for (int i = 20; i >= 0; i--) {
		if (jump[x][i] != jump[y][i])
			x = jump[x][i], y = jump[y][i];
	}
	return jump[x][0];
}
bool cmp(A a, A b) {
	return a.l < b.l;
}
int rmax(int x, int y, int val) {
	int ans = 0;
	for (int i = 20; i >= 0; i--) {
		if (deep[jump[x][i]] >= deep[y]) {
			if (fir[x][i] == val)
				ans = max(ans, sec[x][i]);
			else
				ans = max(ans, fir[x][i]);
			x = jump[x][i];
		}
	}
	return ans;
}
signed main() {
	int ans = LONG_LONG_MAX;
	n = read(), m = read();
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read(), len = read();
		if (x == y) {
			i--, m--;
			continue;
		}
		edge[i] = {x, y, len};
	}
	for (int i = 1; i <= n; i++)
		father[i] = i;
	sort(edge + 1, edge + m + 1, cmp);
	for (int i = 1; i <= m; i++) {
		int x = find(edge[i].x), y = find(edge[i].y);
		if (x != y) {
			sum += edge[i].l;
			father[x] = y;
			used[i] = true;
			tree[edge[i].x].push_back({edge[i].y, edge[i].l});
			tree[edge[i].y].push_back({edge[i].x, edge[i].l});
		}
	}
	finddep(1);
	init();
	for (int i = 1; i <= m; i++) {
		if (used[i]) continue;
		int x = edge[i].x, y = edge[i].y, val = edge[i].l;
		int lca1 = lca(x, y), t = max(rmax(x, lca1, val), rmax(y, lca1, val));
		ans = min(ans, sum + val - t);
	}
	cout << ans;
	return 0;
}

记录

2024/3/24 12:10
加载中...