11月1日上午T2

TonyZhao 的代理服务节点遍布全球。但是他想要去开辟新的领域(比如在大合唱上放音乐 OvO ),于是便将这些节点的控制系统交给了小花。

小花研究了很长时间,发现整个系统是由 NNN 个节点 N−1N-1N1 根网线构成的(当然是联通的,不联通不就出现几个不互联的互联网了嘛 = = ),每根网线都有它的带宽。这个系统的客户众多,每个客户都希望自己能从 aia_iai​​ 号节点访问 bib_ibi​​ 号节点上的数据。

分配系统路线的事情当然是全自动完成的,路径分配系统是 TonyZhao\mathfrak{TonyZhao}TonyZhao 写的——它的算法确保了路径不会经过同一条网线两次。(当然所有网线带宽均 >0\gt 0>0 )但是小花得到了一个任务——她要对整个系统进行更新,也就是要更换网线。为了升级,她需要知道客户的特殊信息——他们的访问路径上所有经过网线中最大的带宽和最小的带宽。这很有利于工程师们分析升级方案,但是并没有可用的系统可以做到这一点。小花于是想到求助 NOIP 2017 将会轻松 AK 的你,请你帮一帮她。

这道题用到了倍增lca,同时倍增求出最大最小值

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int ans1,ans2,val[500005];
int n,m,s,head[500005],nxt[1200000],to[1200000],ce,dep[500005],fa[500005][22],lg[500005],maxx[500005][22],minn[500005][22];
void add(int u,int v,int w){
    to[++ce]=v;nxt[ce]=head[u];head[u]=ce;val[ce]=w;
}
void dfs(int now,int fat){
    dep[now]=dep[fat]+1;
    fa[now][0]=fat;
    for(int i=1;(1<<i)<=dep[now];i++){
        fa[now][i]=fa[fa[now][i-1]][i-1];
        maxx[now][i]=max(maxx[now][i-1],maxx[fa[now][i-1]][i-1]);
        minn[now][i]=min(minn[now][i-1],minn[fa[now][i-1]][i-1]);
    }
    for(int i=head[now];i;i=nxt[i])
        if(to[i]!=fat){
            maxx[to[i]][0]=val[i];
            minn[to[i]][0]=val[i];
          //  printf("%d %d\n",maxx[to[i]][0],minn[to[i]][0]);
            //printf("%d ",val[1]);
            dfs(to[i],now);
        }
}
int lca(int x,int y){
    if(dep[x]<dep[y])
        swap(x,y);
    while(dep[x]>dep[y]){
        ans1=max(ans1,maxx[x][lg[dep[x]-dep[y]]-1]);
        ans2=min(ans2,minn[x][lg[dep[x]-dep[y]]-1]);
        x=fa[x][lg[dep[x]-dep[y]]-1];
    }
    if(x==y) return x;
    for(int i=lg[dep[x]]-1;i>=0;i--)
        if(fa[x][i]!=fa[y][i]){
            int maxn=max(maxx[x][i],maxx[y][i]);
            ans1=max(ans1,maxn);
            int mi=min(minn[x][i],minn[y][i]);
            ans2=min(ans2,mi);
            x=fa[x][i],y=fa[y][i];
        }
    return fa[x][0];
}
int main(){
   // freopen("r.in","r",stdin);
   // freopen("r.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);add(b,a,c);
       //printf("%d\n",val[ce]);
    }
   // printf("%d",val[2]);
    maxx[1][0]=-1,minn[1][0]=2147483647;
    dfs(1,0);
    for(int i=1;i<=n;i++)
        lg[i]=lg[i-1]+((1<<lg[i-1])==i);
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        ans1=-1,ans2=2147483647;
        int x,y;
        scanf("%d%d",&x,&y);
        lca(x,y);
        printf("%d %d\n",ans1,ans2);
        //printf("%d\n",lca(x,y));    
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=20;j++)
            printf("%d %d %d\n",i,j,maxx[i][j]);

    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/NGUalexzhang/p/9888895.html
今日推荐