ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

严格次小生成树 模板 P4180

2022-05-18 16:32:02  阅读:115  来源: 互联网

标签:dep v1 int res ll 生成 fa P4180 模板


注意严格次小这个细节问题

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e5 + 10;
const int M = 3e5 + 10;
int n,m,head[N],tot,nxt[M],to[M],f[N];
ll w[M];

struct node {
	int u,v;
	ll ew;
	bool tag;
	bool operator < (const node& e) const {
		return ew < e.ew;
	}
}edge[M];

void add(int u,int v,ll z) {
	to[++tot] = v,w[tot] = z,nxt[tot] = head[u],head[u] = tot;
}

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

ll kruskal() {
	for(int i = 1;i <= n;i ++) f[i] = i;
	int used = 0;
	ll s = 0;
	sort(edge + 1,edge + 1 + m);
	for(int i = 1;i <= m;i ++) {
		int fu = find(edge[i].u),fv = find(edge[i].v);
		if(fu != fv) {
			f[fv] = fu;
			used ++;
			edge[i].tag = true;
			s += edge[i].ew;
			add(edge[i].u,edge[i].v,edge[i].ew);
			add(edge[i].v,edge[i].u,edge[i].ew);
		}
		if(used == n - 1) break;
	}
	return s;
}

int fa[N][20],dep[N];
ll v1[N][20],v2[N][20];
void dfs(int u,int pa,int x) {
	dep[u] = x;
	for(int i = head[u];i;i = nxt[i]) {
		int v = to[i];
		if(v == pa) continue;
		fa[v][0] = u;
		v1[v][0] = w[i];
		for(int i = 1;i < 20;i ++) {
			fa[v][i] = fa[fa[v][i - 1]][i - 1];
			int pref = fa[v][i - 1];
			v1[v][i] = max(v1[v][i - 1],v1[pref][i - 1]);
			v2[v][i] = max(v2[v][i - 1],v2[pref][i - 1]);
			if(v1[v][i - 1] > v1[pref][i - 1])
				v2[v][i] = max(v2[v][i],v1[pref][i - 1]);
			else if(v1[v][i - 1] < v1[pref][i - 1])
				v2[v][i] = max(v2[v][i],v1[v][i - 1]);
		}
		dfs(v,u,x + 1);
	}
}

int LCA(int x,int y) {
	if(dep[x] < dep[y]) swap(x,y);
	for(int i = 19;i >= 0;i --) {
		if(dep[fa[x][i]] >= dep[y]) {
			x = fa[x][i];
		}
	}
	if(x == y) return x;
	for(int i = 19;i >= 0;i --) {
		if(fa[x][i] != fa[y][i]) {
			x = fa[x][i],y = fa[y][i];
		}
	}
	return fa[x][0];
}

ll calc(int u,int lca,ll z) {
	ll res = 0;
	for(int i = 19;i >= 0;i --) {
		if(dep[fa[u][i]] >= dep[lca]) {
			if(z == v1[u][i]) {
				res = max(res,v2[u][i]);
			} else {
				res = max(res,v1[u][i]);
			}
			u = fa[u][i];
		}
	}
	return res;
}

int main() {
	cin >> n >> m;
	for(int i = 1;i <= m;i ++) {
		int x,y;ll z; cin >> x >> y >> z;
		edge[i].u = x,edge[i].v = y,edge[i].ew = z,edge[i].tag = false;
	}
	ll s = kruskal(),ans = 1e18;
	dfs(1,0,1);
	for(int i = 1;i <= m;i ++) {
		if(edge[i].tag || edge[i].u == edge[i].v) continue;//注意自环直接判掉 不合法
		int lca = LCA(edge[i].u,edge[i].v);
		ll del = max(calc(edge[i].u,lca,edge[i].ew),calc(edge[i].v,lca,edge[i].ew));
		ans = min(ans,s + edge[i].ew - del);
	}
	cout << ans << '\n';
	return 0;
}

标签:dep,v1,int,res,ll,生成,fa,P4180,模板
来源: https://www.cnblogs.com/forward77/p/16285166.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有