一开始想tarjan缩点之后再求倍增求lca的同时直接求最长边的最小值
然后发现还要预处理很多东西
1.强连通分量中的某两个点之间的贡献
2.从强连通分量中走出来连向另一个点的贡献
而我这种码农题就GG的人不就很萎吗?而且数据可能出成一整个强连通分量,直接GG
然后看了题解,说是最长边的最小值肯定在最小生成树上面
题解还说这一结论肥肠显然
然后我一脸懵逼,这怎么证明....
然后接下来我口胡一下
求MST的kruscal算法本身就是在避开最长边,往最短边走
...............口胡完毕
如果这还有疑问的话,我只能mmp了
下面是代码
并不能AC
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
struct bbbbb{
int from,to,value;
}bian[300003];
bool cmp(bbbbb a,bbbbb b){
return a.value<b.value;
}
int to[300003],nex[300003],head[300003],val[300003];
int fa[200003];
int depth[300003],in[300003],out[300003];
int chuo=0,n,m,k,tot,hehe;
int f[200003][25],maxlen[200003][25];
void add(int a,int b,int v){
to[++tot]=b;
nex[tot]=head[a];
head[a]=tot;
val[tot]=v;
}
int find(int x){
if(fa[x]==x){
return x;
}else{
return fa[x]=find(fa[x]);
}
}
void kruscal(){
sort(bian+1,bian+m+1,cmp);
int now=0;
for(int i=1;i<=n;i++){
fa[i]=i;
}
for(int lei=1;lei<=n-1;now++){
int faa=find(bian[now].from);
int fab=find(bian[now].to);
if(faa!=fab){
fa[faa]=fab;
add(bian[now].from,bian[now].to,bian[now].value);
add(bian[now].to,bian[now].from,bian[now].value);
hehe+=bian[now].value;
lei++;
}
}
}
int dfs(int fa,int now){
in[now]=++chuo;
f[now][0]=fa;
for(int i=head[now];i;i=nex[i]){
if(to[i]!=fa){
dfs(now,to[i]);
maxlen[to[i]][0]=val[i];
}
}
out[now]=++chuo;
}
bool pd(int x,int y){
if(in[x]<=in[y]&&out[x]>=out[y]){
return true;
}
return false;
}
int lca(int x,int y){
if(pd(x,y))return x;
if(pd(y,x))return y;
int k=x;
for(int i=20;i>=0;i--){
if(!pd(f[k][i],y)){
k=f[k][i];
}
}
return f[k][0];
}
int ju(int a,int b){
int k=b;
int ans=0;
for(int i=20;i>=0;i--){
if(!pd(f[k][i],a)&&k!=1){
k=f[k][i];
ans=max(ans,maxlen[k][i]);
}
}
return ans;
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int a,b,v;
cin>>bian[i].from>>bian[i].to>>bian[i].value;
}
kruscal();
cout<<hehe<<endl;
dfs(0,1);
for(int i=1;i<=n;i++){
for(int j=1;j<=20;j++){
f[i][j]=f[f[i][j-1]][j-1];
maxlen[i][j]=max(maxlen[maxlen[i][j-1]][j-1],maxlen[i][j-1]);
}
}
for(int i=1;i<=n;i++){
cout<<f[i][1]<<endl;
}
for(int i=1;i<=k;i++){
int a,b;
cin>>a>>b;
int lcalca=lca(a,b);
cout<<"the_lca:"<<lcalca<<endl;
cout<<max(ju(lcalca,a),ju(lcalca,b))<<endl;
}
return 0;
}
/*
in:
6 6 9
1 2 5
2 3 4
3 4 3
1 4 8
2 5 7
4 6 2
1 2
1 3
1 4
2 3
2 4
5 1
6 2
6 1
3 5
out:
5
5
5
4
4
7
4
5
*/