洛谷P1967 货车运输 AC代码
题目链接
#include <bits/stdc++.h>
using namespace std;
int n,m,q;
struct edge{
int u;
int v;
int num;
}e[500005];
bool cmp(edge x,edge y){
return x.num>y.num;
}
int f[100005];
int find(int x){
if(f[x]==x)return x;
return f[x]=find(f[x]);
}
struct line{
int to;
int num;
};
vector<line> ed[100005];
int st,eds;
int lg[100005],vis[100005],dep[100005];
int fa[100005][32],ln[100005][32];
void dofirst(int u,int fat){
vis[u]=1;
fa[u][0]=fat;
dep[u]=dep[fat]+1;
for(int i=1;i<=lg[dep[u]]-1;i++)fa[u][i]=fa[fa[u][i-1]][i-1],ln[u][i]=min(ln[u][i-1],ln[fa[u][i-1]][i-1]);
for(int i=0;i<ed[u].size();i++){
int v=ed[u][i].to;
if(v==fat)continue;
ln[v][0]=ed[u][i].num;
dofirst(v,u);
}
}
int lca(int x,int y){
int ans=999999999;
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y])ans=min(ans,ln[x][lg[dep[x]-dep[y]]-1]),x=fa[x][lg[dep[x]-dep[y]]-1];
if(x==y)return ans;
for(int j=lg[dep[x]]-1;j>=0;j--){
if(fa[x][j]!=fa[y][j]){
ans=min(ans,ln[x][j]);
ans=min(ans,ln[y][j]);
x=fa[x][j];
y=fa[y][j];
}
}
ans=min(ans,ln[x][0]);
ans=min(ans,ln[y][0]);
return ans;
}
int main() {
// freopen("out.txt","w",stdout);
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)f[i]=i,lg[i]=lg[i-1]+(i==1<<lg[i-1]);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].num);
}
sort(e+1,e+m+1,cmp);
int tot=0;
for(int i=1;i<=m;i++){
int fx=find(e[i].u),fy=find(e[i].v);
if(fx!=fy){
f[fx]=fy;
ed[e[i].u].push_back((line){e[i].v,e[i].num});
ed[e[i].v].push_back((line){e[i].u,e[i].num});
tot++;
if(tot==n-1)break;
continue;
}
}
dep[0]=0;
for(int i=1;i<=n;i++){
if(!vis[i])dofirst(i,0);
}
/*
for(int i=1;i<=n;i++){
cout<<i<<':'<<endl;
cout<<"fa:";
for(int j=0;j<=lg[n]-1;j++)cout<<fa[i][j]<<' ';
cout<<endl;
cout<<"ln:";
for(int j=0;j<=lg[n]-1;j++)cout<<ln[i][j]<<' ';
cout<<endl;
}
*/
scanf("%d",&q);
while(q--){
scanf("%d%d",&st,&eds);
if(find(st)!=find(eds)){
printf("-1\n");
continue;
}else{
printf("%d\n",lca(st,eds));
}
}
return 0;
}
不点个推荐再走么?( • ̀ω•́ )✧