社区讨论
RE#10, loj上A了
P4180[BJWC2010] 严格次小生成树参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @lobl37mf
- 此快照首次捕获于
- 2023/10/29 22:46 2 年前
- 此快照最后确认于
- 2023/11/04 03:42 2 年前
CPP
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
//#define int long long
const int N = 2e6;
const LL INF = 1e16;
struct node {
int x, y; LL z;
} e[N];
int tot2, head2[N], nxt2[N], to2[N]; LL w2[N];
int ff[N], dep[N], fa[N];
LL f[N][30], g[N][30][3];
int n, m;
LL minn, max1, max2, val, ans = INF;
int cmp (node x, node y) {
return x.z < y.z;
}
void add2 (int x, int y, LL z) {
to2[++tot2] = y;
w2[tot2] = z;
nxt2[tot2] = head2[x];
head2[x] = tot2;
}
int fd (int x) {
if (x == fa[x]) return x;
else return fa[x] = fd (fa[x]);
}
void kruskal () {
sort (e + 1, e + 1 + m, cmp);
for (int i = 1; i <= m; i ++) {
int fx = fd (e[i].x), fy = fd (e[i].y);
if (fx != fy) {
fa[fx] = fy;
add2 (e[i].x, e[i].y, e[i].z);
add2 (e[i].y, e[i].x, e[i].z);
ff[i] = 1;
minn += e[i].z;
}
}
}
void dfs (int nd, int fa) {
dep[nd] = dep[fa] + 1;
for (int i = 0; i <= 19; i ++) {
f[nd][i + 1] = f[f[nd][i]][i];
g[nd][i + 1][0] = max (g[nd][i][0], g[f[nd][i]][i][0]);
if (g[nd][i][0] == g[f[nd][i]][i][0]) g[nd][i + 1][1] = max (g[nd][i][1], g[f[nd][i]][i][1]);
else if (g[nd][i][0] < g[f[nd][i]][i][0]) g[nd][i + 1][1] = max (g[nd][i][0], g[f[nd][i]][i][1]);
else g[nd][i + 1][1] = max (g[f[nd][i]][i][0], g[nd][i][1]);
}
for (int i = head2[nd]; i; i = nxt2[i]) {
int son = to2[i];
if (son == fa) continue;
f[son][0] = nd;
g[son][0][0] = w2[i];
g[son][0][1] = 0;
dfs (son, nd);
}
}
void lca (int x, int y) {
vector <LL> a;
a.clear();
if (dep[x] < dep[y]) swap (x, y);
for (int i = 20; i >= 0; i --) {
if (dep[f[x][i]] >= dep[y]) {
a.push_back (g[x][i][0]);
a.push_back (g[x][i][1]);
x = f[x][i];
}
// if (x == y) break;
}
if (x != y) {
for (int i = 20; i >= 0; i -- ) {
if (f[x][i] != f[y][i]) {
a.push_back (g[x][i][0]);
a.push_back (g[y][i][0]);
a.push_back (g[x][i][1]);
a.push_back (g[y][i][1]);
x = f[x][i]; y = f[y][i];
}
}
a.push_back (g[x][0][0]);
a.push_back (g[y][0][0]);
}
sort (a.begin(), a.end());
int siz = unique (a.begin(), a.end()) - a.begin();
if (siz >= 2) {
max1 = a[siz - 1];
max2 = a[siz - 2];
}
else {
max1 = a[siz - 1];
max2 = -INF;
}
}
LL solve () {
for (int i = 1; i <= m; i ++) {
if (ff[i]) continue;
lca (e[i].x, e[i].y);
if (e[i].z == max1) ans = min (ans, minn - max2 + e[i].z);
else ans = min (ans, minn - max1 + e[i].z);
}
return ans;
}
int main () {
scanf ("%d%d", &n, &m);
for (int i = 1; i <= n; i ++) fa[i] = i;
for (int i = 1; i <= m; i ++) {
scanf ("%d%d%lld", &e[i].x, &e[i].y, &e[i].z);
}
kruskal ();
dep[1] = 1;
dfs (1, 0);
printf ("%lld\n", solve ());
// return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...