妈的什么乱举报小学生啊。。。。
rt,树剖,样例没过
#include <bits/stdc++.h>
#define int long long
#define inf 1000000010
#define DEBUG puts("done!")
using namespace std;
typedef pair<int, int> PII;
template<typename T>
T read(T x)
{
T opt = 1, sum = 0;
char ch = getchar();
while(!isdigit(ch)) opt = (ch == '-') ? -1 : 1, ch = getchar();
while( isdigit(ch)) sum = (sum << 1) + (sum << 3) + (ch ^ 48), ch = getchar();
return opt * sum;
}
#define read read(0ll)
int n, m;
const int N = 1e5 + 5;
struct Rainy
{
int u, v, w;
}g[N << 2];
struct node
{
int u, v, w, next;
}e[N << 2];
int f[N], tot, w[N], son[N], idx, head[N << 2], ans0, ans = inf, dep[N], top[N], id[N], fa[N], size[N], a[N], _;
bool vis[N];
void add(int u, int v, int w)
{
e[++tot].v = v;e[tot].w = w;e[tot].next = head[u];head[u] = tot;
}
bool cmp(Rainy a,Rainy b){
return a.w < b.w;
}
struct Kruskal
{
int find(int x){
// cout << x << endl;
if(f[x] == x) return x;
else f[x] = find(f[x]);
}
void kruskal()
{
for(int i = 1;i <= n;i ++) f[i] = i;
for(int i = 1;i <= m;i ++) g[i] = {read, read, read};
sort(g + 1, g + 1 + m, cmp);
for(int i = 1;i <= m;i ++ ){
int u = find(g[i].u);
int v = find(g[i].v);
if(u == v) continue;
add(g[i].u, g[i].v, g[i].w), add(g[i].v, g[i].u, g[i].w);
ans0 += g[i].w;
// cout << g[i].w << ' ';
f[v] = u;
vis[i] = 1;
_ ++ ;
if(_ == n - 1) break;
}
}
}kru;
struct TreePou
{
void dfs1(int u, int F, int deep)
{
dep[u] = deep;
fa[u] = F;
size[u] = 1;
int maxn = -1;
for(int i = head[u];i;i = e[i].next) {
int v = e[i].v;
if(v == F) continue;
w[v] = w[u] + e[i].w;
dfs1(v, u, deep + 1);
size[u] += size[v];
if(size[v] > maxn){
maxn = size[v];
son[u] = v;
}
}
}
void dfs2(int u, int topf)
{
top[u] = topf;
id[u] = ++idx;
a[idx] = w[u] - w[fa[u]];
// cout << a[idx] << ' ';
if(!son[u]) return ;
dfs2(son[u], topf);
for(int i = head[u];i;i = e[i].next){
int v = e[i].v;
if(v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
void init()
{
dfs1(1, 0, 1), dfs2(1, 1);
}
}tp;
struct Segment
{
struct Tree
{
int l, r, ma, mex;
}tr[N << 2];
int get(int a, int b, int c, int d)
{
int yexo[4] = {a, b, c, d};
sort(yexo, yexo + 4, greater<int>());
for(int i = 1;i < 4;i ++){
if(yexo[i] != yexo[0]) return yexo[i];
}
}
void push_up(int u){
tr[u].ma = max(tr[u << 1].ma, tr[u << 1 | 1].ma);
tr[u].mex = get(tr[u << 1].ma, tr[u << 1 | 1].ma, tr[u << 1].mex, tr[u << 1 | 1].mex);
}
void build(int u, int l, int r)
{
if(l == r){
tr[u].ma = a[l];
return ;
}
int mid = (l + r) / 2;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
push_up(u);
}
PII query(int u, int l, int r, int ll, int rr)
{
if(ll > r || rr < r) return make_pair(-inf, -inf);
if(ll <= l && rr >= r) {
return make_pair(tr[u].ma, tr[u].mex);
}
int mid = (l + r) >> 1;
PII x = query(u << 1, l, mid, ll, rr), y = query(u << 1 | 1, mid + 1, r, ll, rr);
return make_pair(max(x.first, y.first), get(x.first, y.first, x.second, y.second));
}
}seg;
struct Smaller_Tree
{
int Find(int x, int y, int w)
{
int res = -inf;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x, y);
PII k = seg.query(1, 1, n, id[top[x]], id[x]);
res = max(res, ((k.first == w) ? k.second : k.first));
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
PII k = seg.query(1, 1, n, id[x] + 1, id[y]);
res = max(res, ((k.first == w) ? k.second : k.first));
return res;
}
}st;
signed main()
{
n = read, m = read;
kru.kruskal();
// cout << ans0 << endl;
tp.init(), seg.build(1, 1, n);
for(int i = 1;i <= m;i ++){
if(!vis[i]){
int res = ans0 - st.Find(g[i].u, g[i].v, g[i].w) + g[i].w;
cout << res << ' ' << ans0 << ' ' << e[i].w << endl;
if(ans > res && res > ans0 && res != ans0 + e[i].w){
ans = res;
}
}
}
cout << ans << endl;
return 0;
}