听灌多
  • 板块灌水区
  • 楼主Tomwsc
  • 当前回复4
  • 已保存回复4
  • 发布时间2025/1/23 17:38
  • 上次更新2025/1/23 20:56:32
查看原帖
听灌多
1418967
Tomwsc楼主2025/1/23 17:38

严格次小生成树 wa 77pts 求调:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 1e4 + 10 , MAXM = 3e4 + 10;
int n , m;
struct Edge {
	int u , v , w;
	bool flag;
};
Edge edge[MAXM];
int idx;
int fa[MAXN];
int ans , minn = INT_MAX;
int lca[MAXN][20] , maxt[MAXN][20] , maxf[MAXN][20];
int depth[MAXN];
bool flag[MAXN];
vector<pair<int , int> >mapp[MAXN];

int find(int x) {
	if(fa[x] == x)
		return x;
	return fa[x] = find(fa[x]);
}

inline void merge(int a , int b) {
	int x = find(a);
	int y = find(b);
	fa[x] = y;
	return;
}

inline void add(int a , int b , int c) {
	edge[++ idx].u = a;
	edge[idx].v = b;
	edge[idx].w = c;
	return;
}

inline bool cmp(Edge a , Edge b) {
	return a.w < b.w;
}

inline void Kruskal() {
	int cnt = 0;
	for(register int i = 1;i <= idx;i ++) {
		if(find(edge[i].u) != find(edge[i].v)) {
			merge(edge[i].u , edge[i].v);
			edge[i].flag = true;
			cnt ++;
			ans += edge[i].w;
			mapp[edge[i].u].push_back(make_pair(edge[i].v , edge[i].w));
			mapp[edge[i].v].push_back(make_pair(edge[i].u , edge[i].w));
		}
		if(cnt == n - 1)
			return;
	}
	return;
}

void dfs(int u , int f , int w) {
	depth[u] = depth[f] + 1;
	lca[u][0] = f;
	maxf[u][0] = INT_MIN;
	maxt[u][0] = w;
	for(register int i = 1;i <= 19;i ++) {
		lca[u][i] = lca[lca[u][i - 1]][i - 1];
		maxt[u][i] = max(maxt[u][i - 1] , maxt[lca[u][i - 1]][i - 1]);
		maxf[u][i] = max(maxf[u][i - 1] , maxf[lca[u][i - 1]][i - 1]);
		if(maxt[u][i - 1] > maxt[lca[u][i - 1]][i - 1])	
			maxf[u][i] = max(maxf[u][i] , maxt[lca[u][i - 1]][i - 1]);
		if(maxt[u][i - 1] < maxt[lca[u][i - 1]][i - 1])
			maxf[u][i] = max(maxf[u][i] , maxt[u][i - 1]);
	}
	for(auto i : mapp[u]) {
		if(i.first == f)
			continue;
		dfs(i.first , u , i.second);
	}
	return;
}

inline int LCA(int a , int b) {
	int cnt = INT_MIN;
	if(depth[a] < depth[b])
		swap(a , b);
	for(register int i = 19;i >= 0;i --)
		if(depth[lca[a][i]] >= depth[b])
			a = lca[a][i];
	if(a == b)
		return a;
	for(register int i = 19;i >= 0;i --)
		if(lca[a][i] != lca[b][i]) {
			a = lca[a][i];
			b = lca[b][i];
		}
	return lca[a][0];
}

inline int getmax(int u , int v , int w) {
	int cnt = INT_MIN;
	for(register int i = 19;i >= 0;i --) {
		if(depth[lca[u][i]] >= depth[v]) {
			if(w == maxt[u][i])
				cnt = max(cnt , maxf[u][i]);
			else
				cnt = max(cnt , maxt[u][i]);
			u = lca[u][i];
		}
	}
	return cnt;
}

inline void solve() {
	dfs(1 , 0 , 0);
	int maxn1 = INT_MIN;
	int maxn2 = INT_MIN;
	for(register int i = 1;i <= idx;i ++) {
		if(!edge[i].flag) {
			int u = edge[i].u;
			int v = edge[i].v;
			int Lca = LCA(u , v);
			maxn1 = getmax(u , Lca , edge[i].w);
			maxn2 = getmax(v , Lca , edge[i].w);
		}
		minn = min(minn , ans + edge[i].w - max(maxn1 , maxn2));
	}
	return;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	while(m --) {
		int u , v , w;
		cin >> u >> v >> w;
		if(u != v)
			add(u , v , w);
	}
	for(register int i = 1;i <= n;i ++)
		fa[i] = i;
	sort(edge + 1 , edge + 1 + idx , cmp);
	Kruskal();
	solve();
	cout << minn;
	return 0;
}
2025/1/23 17:38
加载中...