社区讨论
树剖 WA on #12
P4180[BJWC2010] 严格次小生成树参与者 3已保存回复 6
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @lo8a5tba
- 此快照首次捕获于
- 2023/10/27 15:16 2 年前
- 此快照最后确认于
- 2023/10/27 15:16 2 年前
rt 还是我
既 TLE 之后又 WA 了 答案好像偏小
CPP#include<bits/stdc++.h>
#define debug() puts("chaotic ak ioi")
#define LL long long
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
inline LL read(){
LL res=0,fl=1;
char ch=getchar();
while(!(ch>='0' && ch<='9')){if(ch=='-')fl=-1;ch=getchar();}
while(ch>='0' && ch<='9')res=(res<<3)+(res<<1)+ch-'0',ch=getchar();
return res*fl;
}
inline LL max(LL a,LL b){return a>b?a:b;}
inline LL min(LL a,LL b){return a<b?a:b;}
inline void swap(int &a,int &b){int c;c=a;a=b;b=c;}
const int MAXN=1e6+5;
int n,m,tot=0,p[MAXN];
LL ans=1e18;
int si[MAXN],dep[MAXN],fa[MAXN],son[MAXN],wson[MAXN],id[MAXN],top[MAXN],sp[MAXN];
bool tri[MAXN];
struct Edge{
int v,w;
};
vector<Edge> e[MAXN];
struct wEdge{
int x,y,w,id;
}a[MAXN];
struct Segment_Tree{
int l,r,maxv,smax;
#define ls (k<<1)
#define rs (k<<1|1)
#define l(k) tr[k].l
#define r(k) tr[k].r
#define maxv(k) tr[k].maxv
#define smax(k) tr[k].smax
#define mid(k) ((tr[k].l+tr[k].r)>>1)
}tr[MAXN<<2];
inline pair<int,int> merge(int a,int b,int c,int d){
int t[4]={a,b,c,d};
sort(t,t+4);
int maxv=t[3],smax=-1;
for(int i=2;i>=0;i--)if(t[i]!=t[i+1]){smax=t[i];break;}
return make_pair(maxv,smax);
}
inline void pushup(int k){
pair<int,int> p=merge(maxv(ls),smax(ls),maxv(rs),smax(rs));
maxv(k)=p.first,smax(k)=p.second;
}
inline void build(int k,int l,int r){
l(k)=l,r(k)=r;
if(l==r){
maxv(k)=sp[l];
smax(k)=-1;
return;
}
build(ls,l,mid(k));
build(rs,mid(k)+1,r);
pushup(k);
}
inline pair<int,int> query(int k,int l,int r){
if(l(k)>=l && r(k)<=r) return make_pair(maxv(k),smax(k));
pair<int,int> lres,rres;
if(l<=mid(k) && r<=mid(k))return query(ls,l,r);
if(l>mid(k) && r>mid(k))return query(rs,l,r);
lres=query(ls,l,r),rres=query(rs,l,r);
return merge(lres.first,lres.second,rres.first,rres.second);
}
inline bool cmp(wEdge a,wEdge b){
return a.w<b.w;
}
inline int find(int x){
if(p[x]==x)return x;
return p[x]=find(p[x]);
}
inline void dfs_son(int x,int f,int d){
si[x]=1;
dep[x]=d;
fa[x]=f;
int maxson=0;
for(int i=0;i<e[x].size();i++){
int y=e[x][i].v,w=e[x][i].w;
if(y!=f){
dfs_son(y,x,d+1);
si[x] += si[y];
if(si[y]>maxson)maxson=si[y],son[x]=y,wson[x]=w;
}
}
}
inline void dfs_chain(int x,int topf,int z){
id[x]=++tot;
sp[tot]=z;
top[x]=topf;
if(!son[x])return;
dfs_chain(son[x],topf,wson[x]);
for(int i=0;i<e[x].size();i++){
int y=e[x][i].v,w=e[x][i].w;
if(y!=fa[x] && y!=son[x])dfs_chain(y,y,w);
}
}
inline int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
return x;
}
inline int findson(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
if(fa[top[x]]==y)return top[x];
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
return son[x];
}
inline pair<int,int> range_query(int x,int y){
pair<int,int> res=make_pair(-1,-1),tmp;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
tmp=query(1,id[top[x]],id[x]);
res=merge(res.first,res.second,tmp.first,tmp.second);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
tmp=query(1,id[x],id[y]);
res=merge(res.first,res.second,tmp.first,tmp.second);
return res;
}
signed main() {
memset(tri,0,sizeof tri);
int x,y,w,px,py,eid,minw=0;
n=read(),m=read();
for(int i=1;i<=n;i++)p[i]=i;
for(int i=1;i<=m;i++){
x=read(),y=read(),w=read();
a[i]={x,y,w,i};
}
sort(a+1,a+1+m,cmp);
int tcnt=0;
for(int i=1;i<=m;i++){
x=a[i].x,y=a[i].y,w=a[i].w,eid=a[i].id;
px=find(x),py=find(y);
if(px!=py){
e[x].push_back({y,w});
e[y].push_back({x,w});
p[px]=py;
tri[eid]=1;
minw+=w;
tcnt++;
}
if(tcnt==n-1)break;
}
dfs_son(1,1,1);
dfs_chain(1,1,0);
build(1,1,n);
int rt,sonx,sony;
for(int i=1;i<=m;i++){
x=a[i].x,y=a[i].y,w=a[i].w,eid=a[i].id;
if(tri[eid] || x==y)continue;
rt=lca(x,y);
sonx=findson(x,rt),sony=findson(y,rt);
pair<int,int> p,l,r;
l=range_query(x,sonx);
r=range_query(y,sony);
p=merge(l.first,l.second,r.first,r.second);
int secw=p.first==w?p.second:p.first,smin=minw+w-secw;
if(secw==-1)continue;
ans=min(ans,smin);
}
cout<<ans<<'\n';
return 0;
}
回复
共 6 条回复,欢迎继续交流。
正在加载回复...