社区讨论
最大生成树+lca 0分求助(
P1967[NOIP 2013 提高组] 货车运输参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lo2ox4k8
- 此快照首次捕获于
- 2023/10/23 17:23 2 年前
- 此快照最后确认于
- 2023/10/23 17:23 2 年前
C
#include<cstdio>
#include<algorithm>
#define inf 999999999
using namespace std;
const int N=1e4+5,M=1e5+5;
inline int read(){
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=(x<<3)+(x<<1)+c-48;
c=getchar();
}
return x*f;
}
struct edge1{
int x,y,dis;
}e1[M];
struct edge2{
int to,nxt,w;
}e2[M];
int n,m,q,cnt,f[N];
int head[N],dep[N],fa[N][25],w[N][25];
bool vis[N];
inline void add_edge(int u,int v,int w){
cnt++;
e2[cnt].nxt=head[u];
e2[cnt].to=v;
e2[cnt].w=w;
head[u]=cnt;
}
bool cmp(edge1 a,edge1 b){
return a.dis>b.dis;
}
int find(int x){
if(x==f[x])return x;
return f[x]=find(f[x]);
}
void kruskal(){
for(int i=1;i<=m;i++){
int x=find(e1[i].x),y=find(e1[i].y);
if(x!=y){
f[x]=y;
add_edge(e1[i].x,e1[i].y,e1[i].dis);
add_edge(e1[i].y,e1[i].x,e1[i].dis);
}
}
}
inline void dfs(int p){
vis[p]=1;
for(int i=head[p];i;i=e2[i].nxt){
int v=e2[i].to;
if(vis[v])continue;
dep[v]=dep[p]+1;
fa[v][0]=p;
w[v][0]=e2[i].w;
dfs(v);
}
}
int lca(int x,int y){
int ans=inf;
if(dep[x]>dep[y])swap(x,y);
for(int i=20;i>=0;i--)
if(dep[fa[y][i]]>=dep[x]){
ans=min(ans,w[y][i]);
y=fa[y][i];
}
if(x==y)return ans;
for(int i=20;i>=0;i--)
if(fa[x][i]!=fa[y][i]){
ans=min(ans,min(w[x][i],w[y][i]));
x=fa[x][i];
y=fa[y][i];
}
ans=min(ans,min(w[x][0],w[y][0]));
return ans;
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++){
e1[i].x=read();
e1[i].y=read();
e1[i].dis=read();
}
sort(e1+1,e1+m+1,cmp);
for(int i=1;i<=n;i++)f[i]=i;
kruskal();
for(int i=1;i<=n;i++){
if(vis[i])continue;
dep[i]=1;
dfs(i);
fa[i][0]=i;
w[i][0]=inf;
}
for(int i=1;i<=20;i++)
for(int j=1;j<=n;j++){
fa[j][i]=fa[fa[j][i-1]][i-1];
w[j][i]=min(w[j][i-1],w[fa[j][i-1]][i-1]);
}
q=read();
while(q--){
int x=read(),y=read();
if(find(x)!=find(y))printf("-1");
else printf("%d\n",lca(x,y));
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...