社区讨论
树剖线段树为何30
P14080[GESP202509 八级] 最小生成树参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mhj347w0
- 此快照首次捕获于
- 2025/11/03 19:56 4 个月前
- 此快照最后确认于
- 2025/11/03 19:56 4 个月前
全过,其余全WA
puts30记录
CPP#include<bits/stdc++.h>
#define ll long long
#define int long long
#define ls rt<<1
#define rs rt<<1|1
#define mid ((l+r)>>1)
#define lson ls,l,mid
#define rson rs,mid+1,r
using namespace std;
const int N = 1e5 + 10;
const ll INF = 1e10;
template<typename TY>
inline void read(TY &s){
ll x = 0, f = 1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
s = x * f;
}
struct edge{
int u,v; ll w; int k2,id;
edge(int a=0,int b=0,ll c=0){
u=a,v=b,w=c;
}
bool operator<(const edge &o) const{return k2==o.k2 ? w < o.w : k2 < o.k2;}
}E[N];
vector<edge> e[N];
int n,m,f[N],cnt;
ll sum;
int find(int x){
if(f[x] != x) f[x] = find(f[x]);
return f[x];
}
int fa[N],son[N],deep[N],top[N],siz[N],dfn[N],pos[N],tim;
void dfs1(int u){
// cerr<<u<<"u\n";
deep[u] = deep[fa[u]] + 1; siz[u] = 1;
for(auto x : e[u]){
if(x.v == fa[u]) continue;
fa[x.v] = u; dfs1(x.v);
siz[u] += siz[x.v];
if(!son[u]||siz[son[u]] < siz[x.v]) son[u] = x.v;
}
}
void dfs2(int u,int topx){
top[u] = topx;
dfn[u] = ++tim; pos[tim] = u;
if(son[u]) dfs2(son[u],topx);
for(auto x : e[u]){
if(x.v == fa[u] || x.v == son[u]) continue;
dfs2(x.v,x.v);
}
}
int c[N<<2],tag[N<<2],ans[N];
inline void push_down(int rt,int l,int r){
if(tag[rt]){
c[ls] = c[rs] = tag[ls] = tag[rs] = tag[rt];
tag[rt] = 0;
}
}
void modify(int rt,int l,int r,int ql,int qr,int v){
// cerr << rt << "rt ->";
if(tag[rt]||c[rt]) return;
if(ql <= l && r <= qr){
// cerr<<pos[l] << " " << pos[r] << "pos\n";
c[rt] = tag[rt] = v;
return;
}
push_down(rt,l,r);
if(ql <= mid) modify(lson,ql,qr,v);
if(mid + 1 <= qr) modify(rson,ql,qr,v);
}
ll query(int rt,int l,int r,int x){
if(l == r) return c[rt];
push_down(rt,l,r);
if(x <= mid) return query(lson,x);
else return query(rson,x);
}
inline void change(int x,int y,int v){
// cerr<<"change into\n";
while(top[x]!=top[y]){
if(deep[top[x]] < deep[top[y]]) swap(x,y);
modify(1,1,n,dfn[top[x]],dfn[x],v);
x = fa[top[x]];
}
if(x == y) return;
if(deep[x] > deep[y]) swap(x,y);
modify(1,1,n,dfn[x]+1,dfn[y],v);
// cerr << "change out\n";
}
signed main(){
read(n); read(m);
for(int i=1;i<=m;i++){
read(E[i].u); read(E[i].v); read(E[i].w);
E[i].id = i; E[i].k2 = 0;
}
for(int i=1;i<=n;i++) f[i] = i;
sort(E+1,E+m+1);
for(int i=1;i<=m;i++){
int u = find(E[i].u), v = find(E[i].v);
if(u == v) continue;
f[v] = u;
sum += E[i].w; E[i].k2 = 1;
e[E[i].u].push_back(edge(E[i].u,E[i].v,E[i].w));
e[E[i].v].push_back(edge(E[i].v,E[i].u,E[i].w));
if(++cnt >= n-1) break;
}
dfs1(1); dfs2(1,1);
sort(E+1,E+m+1);
for(int i=1;i<=m;i++){
if(E[i].k2) break;
int u = E[i].u , v = E[i].v;
// cerr<<u<<" "<<v<<"?????\n";
change(u,v,E[i].w);
}
for(int i=1;i<=m;i++){
int u = E[i].u , v = E[i].v;
if(!E[i].k2){
ans[E[i].id] = sum;
continue;
}
if(deep[u] > deep[v]) swap(u,v);
int k = query(1,1,n,dfn[v]);
ans[E[i].id] = k ? sum - E[i].w + k : -1;
}
for(int i=1;i<=m;i++){
cout << ans[i] << "\n";
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...