建议加强数据
查看原帖
建议加强数据
528287
多喝岩浆楼主2023/3/23 20:53

MnZn样例没过但A了。。。

建议把样例加入数据

#include<bits/stdc++.h>
#define int long long
#define PP pair <int, int>

using namespace std;

inline int read () {
	int s = 0, f = 1;
	char ch = getchar ();
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -1;
		ch = getchar ();
	}
	while (ch >= '0' && ch <= '9') {
		s = (s << 1) + (s << 3) + (ch ^ 48);
		ch = getchar ();
	}
	return s * f;
}

const int N = 3e5 + 10, INF = 4e18;

struct EDGE {
	int next, to, z;
} edge[N * 2];

struct fdsa {
	int x, y, z;
	inline bool operator < (const fdsa& asdf) const {
		return z < asdf.z;
	}
} e[N];

int head[N], cnt, n, fa[N][30], w[N][30][2], dep[N], m, res, asdfasdfasdf;

int Fa[N];

bool f[N];

map <PP, bool> mm; 

int get (int x) {
	if (x == Fa[x]) return x;
	return Fa[x] = get (Fa[x]);
}

inline void add (int x, int y, int z) {
	edge[ ++ cnt].next = head[x];
	edge[cnt].to = y;
	edge[cnt].z = z;
	head[x] = cnt;
}

void dfs (int x, int fffff) {
	for (int i = 1; i < 20; i ++ ) {
		fa[x][i] = fa[fa[x][i - 1]][i - 1];
		w[x][i][0] = max (w[x][i][0], max (w[fa[x][i - 1]][i - 1][0], w[x][i - 1][0]));
		if (w[x][i - 1][0] == w[fa[x][i - 1]][i - 1][0]) w[x][i][1] = max (w[x][i][1], max (w[x][i - 1][1], w[fa[x][i - 1]][i - 1][1]));
		if (w[x][i - 1][0] > w[fa[x][i - 1]][i - 1][0]) w[x][i][1] = max (w[x][i][1], max (w[x][i - 1][1], w[fa[x][i - 1]][i - 1][0]));
		if (w[x][i - 1][0] < w[fa[x][i - 1]][i - 1][0]) w[x][i][1] = max (w[x][i][1], max (w[x][i - 1][0], w[fa[x][i - 1]][i - 1][1]));
	}
	for (int i = head[x]; i; i = edge[i].next) {
		int y = edge[i].to, z = edge[i].z;
		if (y == fffff) continue;
		fa[y][0] = x;
		w[y][0][0] = z;
		w[y][0][1] = -INF;
		dep[y] = dep[x] + 1;
		dfs (y, x);
	}
}

inline PP query (int x, int y) {
	if (x == y) return {0, 0};
	int res1 = -INF, res2 = -INF;
	if (dep[x] < dep[y]) swap (x, y);
	for (int i = 19; i >= 0; i -- )
		if (dep[fa[x][i]] >= dep[y]) {
			if (w[x][i][0] > res1) {
				res2 = res1;
				res1 = w[x][i][0];
			}
			if (w[x][i][1] > res2) res2 = w[x][i][1];
			x = fa[x][i];
		}
	if (x == y) return {res1, res2};
	for (int i = 19; i >= 0; i -- )
		if (fa[x][i] != fa[y][i]) {
			if (w[x][i][0] > res1) {
				res2 = res1;
				res1 = w[x][i][0];
			}
			if (w[x][i][1] > res2) res2 = w[x][i][1];
			x = fa[x][i];
			if (w[y][i][0] > res1) {
				res2 = res1;
				res1 = w[y][i][0];
			}
			if (w[y][i][1] > res2) res2 = w[y][i][1];
			y = fa[y][i];
		}
	if (w[x][0][0] > res1) {
		res2 = res1;
		res1 = w[x][0][0];
	}
	if (w[x][0][1] > res2) res2 = w[x][0][1];
	if (w[y][0][0] > res1) {
		res2 = res1;
		res1 = w[y][0][0];
	}
	if (w[y][0][1] > res2) res2 = w[y][0][1];
	asdfasdfasdf = fa[x][0];
	return {res1, res2};
}

signed main () {
	n = read (), m = read ();
	for (int i = 1; i <= n; i ++ ) Fa[i] = i; // 并查集初始化 
	for (int i = 1; i <= m; i ++ ) 
		e[i].x = read (), e[i].y = read (), e[i].z = read ();
	sort (e + 1, e + m + 1);
	for (int i = 1; i <= m; i ++ ) { // 最小生成树 
		int x = get (e[i].x), y = get (e[i].y), z = e[i].z;
		if (e[i].x == e[i].y) {
			f[i] = 1;
			continue;
		}
		if (x == y) continue;
		add (e[i].x, e[i].y, z); // 建树 
		add (e[i].y, e[i].x, z);
		Fa[x] = y;
		res += z;
		f[i] = 1;
	}
	dep[1] = 1
	dfs (1, 0);
	int ans = INF;
	for (int i = 1; i <= m; i ++ ) { // 枚举每一条边,让它成为最小生成树的一边。为了严格次大,所以去掉树中最大的边,换上这条边 
		if (f[i]) continue;
	 	PP asdf = query  (e[i].x, e[i].y);
	 	int s1 = asdf.first, s2 = asdf.second;
	 	if (s1 != e[i].z) ans = min (ans, res - s1 + e[i].z);
	 	else ans = min (ans, res - s2 + e[i].z);
	}
	cout << ans << endl;
	return 0;
}
2023/3/23 20:53
加载中...