2011 USP Try-outs F. Auction of Services

题意:给出一个图,Q个询问,问2点之间所有路径的最大值的最小值,单条路劲的最大值为该路径中边权最大的

思路:最小生成树+树上倍增lca

http://codeforces.com/gym/101081/problem/F

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 
  4 struct node{
  5     int x,y;
  6     int len;
  7 }a[200005];
  8 int f[100005];
  9 struct edge{
 10     int to,next,val;
 11 }e[200005];
 12 int head[100005],tot;
 13 
 14 bool cmp(node p,node q){
 15     return p.len<q.len;
 16 }
 17 
 18 int hh(int x){
 19     if(f[x]==x) return x;
 20     return f[x]=hh(f[x]);
 21 }
 22 int Find(int x,int y){
 23     int xx=hh(x);
 24     int yy=hh(y);
 25     if(xx!=yy){
 26         f[xx]=yy;return 1;
 27     }
 28     return 0;
 29 }
 30 void add(int u,int v,int val){
 31     e[tot].to=v;
 32     e[tot].val=val;
 33     e[tot].next=head[u];
 34     head[u]=tot++;
 35 }
 36 
 37 int fa[100005][22],deep[100005],d1[100005][22];
 38 void dfs(int u,int ffa){
 39     for(int i=1;i<=20;i++){
 40         if(deep[u]<(1<<i)) break;
 41         fa[u][i]=fa[fa[u][i-1]][i-1];
 42         d1[u][i]=max(d1[u][i-1],d1[fa[u][i-1]][i-1]);
 43     }
 44 
 45     for(int i=head[u];i!=-1;i=e[i].next){
 46         if(e[i].to==ffa) continue;
 47         int v=e[i].to;
 48         fa[v][0]=u;
 49         d1[v][0]=e[i].val;
 50         deep[v]=deep[u]+1;
 51         dfs(v,u);
 52     }
 53 }
 54 
 55 int lca(int x,int y){
 56     if(deep[x]<deep[y])swap(x,y);
 57     int t=deep[x]-deep[y];
 58     for(int i=0;i<=20;i++)
 59         if((1<<i)&t)x=fa[x][i];
 60     for(int i=20;i>=0;i--)
 61     {
 62         if(fa[x][i]!=fa[y][i])
 63         {x=fa[x][i];y=fa[y][i];}
 64     }
 65     if(x==y)return x;
 66     return fa[x][0];
 67 }
 68 
 69 int slove(int x,int y){//y在上
 70     int t=deep[x]-deep[y];
 71    // cout<<x<<" "<<y<<"#"<<endl;
 72    // cout<<deep[x]<<" "<<deep[y]<<" "<<t<<endl;
 73     int Max=0;
 74     for(int i=0;i<=20;i++){
 75         if(t&(1<<i)){
 76            // cout<<i<<" "<<x<<" "<<d1[x][1]<<endl;
 77            Max=max(Max,d1[x][i]);
 78             x=fa[x][i];
 79         }
 80 
 81     }
 82     return Max;
 83 }
 84 
 85 int main(){
 86     int n,m;
 87     cin>>n>>m;
 88     for(int i=1;i<=n;i++) f[i]=i;
 89     memset(head,-1,sizeof(head));
 90     for(int i=1;i<=m;i++){
 91         scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].len);
 92     }
 93     sort(a+1,a+1+m,cmp);
 94     for(int i=1;i<=m;i++){
 95         int xx=a[i].x,yy=a[i].y;
 96        if(Find(xx,yy)){
 97            add(xx,yy,a[i].len);
 98            add(yy,xx,a[i].len);
 99        }
100     }
101     dfs(1,0);
102    // cout<<d1[4][1]<<endl;
103     int q;
104     scanf("%d",&q);
105     for(int i=1;i<=q;i++){
106         int x,y;
107         scanf("%d%d",&x,&y);
108         int k=lca(x,y);
109        // cout<<k<<endl;
110         cout<<max(slove(x,k),slove(y,k))<<endl;
111     }
112 }
原文地址:https://www.cnblogs.com/hhxj/p/7515947.html