社区讨论
5pts玄关求调,树剖+ST表
P1967[NOIP 2013 提高组] 货车运输参与者 2已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mhj40s1w
- 此快照首次捕获于
- 2025/11/03 20:22 4 个月前
- 此快照最后确认于
- 2025/11/03 20:22 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
const int maxm=5e4+5;
int n,m;
int dep[maxn],top[maxn],wc[maxn],pa[maxn],sz[maxn],dfn[maxn],rdfn[maxn],tot;
int fa[maxn],wei[maxn];
int lg[maxn],st[maxn][25];
int getf(int x){return x==fa[x]?fa[x]:fa[x]=getf(fa[x]);}
void uni(int x,int y){fa[getf(x)]=getf(y);}
struct edge{int v,w;};
struct edge2{int u,v,w;}ed[maxm];
bool cmp(edge2 a,edge2 b){return a.w>b.w;}
vector<edge> e[maxn];
void dfs1(int u,int p){
dfn[u]=++tot;
rdfn[tot]=u;
dep[u]=dep[p]+1;
pa[u]=p;
sz[u]=1;
for(auto[v,w]:e[u]){
if(v==p)continue;
wei[v]=w;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[wc[u]])wc[u]=v;
}
}
void dfs2(int u,int tp){
top[u]=tp;
if(wc[u])dfs2(wc[u],tp);
for(auto[v,w]:e[u]){
if(v==pa[u]||v==wc[u])continue;
dfs2(v,v);
}
}
void init(){
lg[1]=0;
for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;
for(int i=1;i<=n;i++){
if(pa[rdfn[i]]==0)continue;
st[i][0]=wei[rdfn[i]];
}
for(int j=1;j<=lg[n];j++){
for(int i=1;i+(1<<j)-1<=n;i++){
st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
}
int query(int l,int r){
if(l>r)return 0x3f3f3f3f;
int k=lg[r-l+1];
return min(st[l][k],st[r-(1<<k)+1][k]);
}
int getmin(int u,int v){
int ans=0x3f3f3f3f;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans=min(ans,query(dfn[top[u]],dfn[u]));
u=pa[top[u]];
}
if(u==v)return ans;
if(dep[u]<dep[v])swap(u,v);
ans=min(ans,query(dfn[v]+1,dfn[u]));
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++)cin>>ed[i].u>>ed[i].v>>ed[i].w;
sort(ed+1,ed+m+1,cmp);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++){
int fu=getf(ed[i].u),fv=getf(ed[i].v);
if(fu!=fv){
uni(ed[i].u,ed[i].v);
e[ed[i].u].push_back({ed[i].v,ed[i].w});
e[ed[i].v].push_back({ed[i].u,ed[i].w});
}
}
for(int i=1;i<=n;i++)if(!dfn[i])wei[i]=0x3f3f3f3f,dfs1(i,0),dfs2(i,i);
init();
int q;
cin>>q;
for(int i=1,u,v;i<=q;i++){
cin>>u>>v;
if(getf(u)!=getf(v))cout<<-1<<endl;
else cout<<getmin(u,v)<<endl;
}
return 0;
}
(在你眼前的是一个LCA只会树剖不会倍增但是会ST表的稀有动物)
回复
共 5 条回复,欢迎继续交流。
正在加载回复...