社区讨论
样例过了但0pts求条
P9235[蓝桥杯 2023 省 A] 网络稳定性参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mhj39drz
- 此快照首次捕获于
- 2025/11/03 20:00 4 个月前
- 此快照最后确认于
- 2025/11/03 20:00 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
struct edge{
int u,v,w;
}e[300010];
int to[300010],nxt[300010],val[300010];
int head[100010],f[100010],d[100010];
int fa[100010][30],mn[100010][30];
bool used[100010];
int n,m,q,t,cnt;
void add(int u,int v,int w){
to[++t]=v;
nxt[t]=head[u];
val[t]=w;
head[u]=t;
}
bool cmp(edge x,edge y){
return x.w>y.w;
}
int find(int x){
if(f[x]==x) return x;
return f[x]=find(f[x]);
}
void dfs(int x,int fath){
used[x]=1;
d[x]=d[fath]+1;
fa[x][0]=fath;
for(int i=1;i<=28;i++){
fa[x][i]=fa[fa[x][i-1]][i-1];
mn[x][i]=min(mn[fa[x][i-1]][i-1],mn[x][i]);
}
for(int i=head[x];i;i=nxt[i]){
if(to[i]==fath) continue;
mn[to[i]][0]=val[i];
dfs(to[i],x);
}
}
int LCA(int u,int v){
int mnu=0x3f3f3f3f,mnv=0x3f3f3f3f;
if(d[u]>d[v]) swap(u,v);
for(int i=28;i>=0;i--){
if(d[fa[v][i]]>=d[u]){
mnv=min(mnv,mn[v][i]);
v=fa[v][i];
}
}
if(u==v) return mnv;
for(int i=28;i>=0;i--){
if(fa[u][i]!=fa[v][i]){
mnu=min(mnu,mn[u][i]);
mnv=min(mnv,mn[v][i]);
u=fa[u][i],v=fa[v][i];
}
}
mnu=min(mnu,mn[u][0]);
mnv=min(mnv,mn[v][0]);
return min(mnu,mnv);
}
int main(){
memset(mn,0x3f,sizeof(mn));
cin>>n>>m>>q;
for(int i=1;i<=m;i++){
cin>>e[i].u>>e[i].v>>e[i].w;
}
sort(e+1,e+m+1,cmp);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++){
int fx=find(e[i].u),fy=find(e[i].v);
if(fx!=fy){
f[fx]=fy;
cnt++;
add(e[i].u,e[i].v,e[i].w),add(e[i].v,e[i].u,e[i].w);
if(cnt==n-1) break;
}
}
for(int i=1;i<=n;i++) if(!used[i]) dfs(i,0);
// for(int i=1;i<=n;i++){
// for(int j=0;j<=2;j++){
// cout<<mn[i][j]<<" ";
// }
// cout<<endl;
// }
while(q--){
int u,v;
cin>>u>>v;
if(find(u)!=find(v)){
cout<<-1<<"\n";
continue;
}
cout<<LCA(u,v)<<"\n";
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...