求助啊,TLE2+WA2,思想为重剖,处理次大最大。
为什么会WA2点,TLE2点,讨论区从未有这种情况,求助!
#include<bits/stdc++.h>
#define N 300100
#define int long long
using namespace std;
int n, m;
int w_new[N];
struct node{
int u, v, w;
}edge[N];
struct node2{
int to, w;
};
struct node3{
int nowmax, nextmax;
}tree[N<<3];
vector<node2> vec[N];
bool cmp(node x, node y) {
return x.w < y.w;
}
int is[N], father[N];
int find(int index) {
if(father[index] == index) {
return index;
}
return father[index] = find(father[index]);
}
int size[N], son[N], wson[N], new_w[N], top[N], dfn[N], ti, fa[N], depth[N];
void dfs1(int index, int back) {
size[index] = 1;
for(int i=0; i<vec[index].size(); ++i) {
if(vec[index][i].to == back) continue;
dfs1(vec[index][i].to, index);
size[index] += size[vec[index][i].to];
if(son[index] == 0 || size[vec[index][i].to] > size[son[index]]) {
son[index] = vec[index][i].to; wson[index] = vec[index][i].w;
}
}
}
void dfs2(int index, int back, int tp) {
top[index] = tp;fa[index] = back; dfn[index]=++ti;
depth[index] = depth[back]+1;
if(son[index]) {
dfs2(son[index], index, tp);
w_new[dfn[son[index]]] = wson[index];
}
for(int i=0; i<vec[index].size(); ++i) {
if(vec[index][i].to == back || vec[index][i].to == son[index]) continue;
dfs2(vec[index][i].to, index, vec[index][i].to);
w_new[dfn[vec[index][i].to]] = vec[index][i].w;
}
}
node3 update(node3 y, node3 z) {
node3 x;
node3 a=y, b=z;
if(a.nowmax > b.nowmax) {
x.nowmax = a.nowmax;
x.nextmax = max(b.nowmax, a.nextmax);
return x;
}
if(a.nowmax < b.nowmax) {
x.nowmax = b.nowmax;
x.nextmax = max(a.nowmax, b.nextmax);
return x;
}
if(a.nowmax == b.nowmax) {
x.nowmax = a.nowmax;
x.nextmax = max(a.nextmax, b.nextmax);
return x;
}
}
void build(int l, int r, int index) {
if(l==r) {
tree[index].nowmax = w_new[l];
tree[index].nextmax = 0;
return;
}
int mid = l + r >> 1;
build(l, mid, index*2); build(mid+1, r, index*2+1);
tree[index] = update(tree[index*2], tree[index*2+1]);
}
node3 ask(int l, int r, int index, int left, int right) {
node3 temp; temp.nextmax = 0; temp.nowmax = 0;
if(left > right) {
return temp;
}
if(l > right || r < left) return temp;
if(l>=left && r<=right) {
temp.nextmax = tree[index].nextmax;
temp.nowmax = tree[index].nowmax;
return temp;
}
int mid = l + r >> 1;
node3 tempx = ask(l, mid, index*2, left, right), tempy = ask(mid+1, r, index*2+1, left, right);
temp = update(tempx, tempy);
return temp;
}
node3 Ask(int l, int r) {
node3 ans; ans.nextmax = 0; ans.nowmax = 0;
while(top[l] != top[r]) {
if(depth[top[l]] > depth[top[r]]) {
swap(l, r);
}
node3 temp = ask(1, n, 1, dfn[top[r]], dfn[r]);
ans = update(temp, ans);
r = father[top[r]];
}
if(depth[l] > depth[r]) {
swap(l, r);
}
node3 temp = ask(1, n, 1, dfn[l]+1, dfn[r]);
ans = update(temp, ans);
return ans;
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> m;
for(int i=1; i<=n; ++i) father[i] = i;
for(int i=1; i<=m; ++i) {
cin >> edge[i].u >> edge[i].v >> edge[i].w;
}
sort(edge+1, edge+1+m, cmp);
int tot = 0, sum = 0;
for(int i=1; i<=n; ++i) {
father[i] = i;
}
for(int i=1; i<=8*n; ++i) {
tree[i].nextmax = tree[i].nowmax = 0;
}
for(int i=1; i<=m; ++i) {
if(find(edge[i].u) != find(edge[i].v)) {
is[i] = 1;father[find(edge[i].u)] = find(edge[i].v);
vec[edge[i].u].push_back({edge[i].v, edge[i].w}); vec[edge[i].v].push_back({edge[i].u, edge[i].w});
sum += edge[i].w; tot++;
}
if(tot == n-1) {
break;
}
}
dfs1(1, 0); dfs2(1, 0, 1); build(1, n, 1);
int ans = 1e18;
for(int i=1; i<=m; ++i) {
if(is[i]) continue;
node3 tempu = Ask(edge[i].u, edge[i].v);
if(tempu.nowmax == edge[i].w) {
if(tempu.nextmax == 0) {
continue;
} else {
int temp = sum + edge[i].w - tempu.nextmax;
if(temp<ans) ans=temp;
}
} else if(tempu.nowmax != 0){
int temp = sum + edge[i].w - tempu.nowmax;
if(temp<ans) ans=temp;
}
}
if(ans == 1e18) {
cout << "sto PinkieRabbit orz";
} else {
cout << ans;
}
return 0;
}