Gym - 101889I Imperial roads (树链剖分维护边权最大值)

Gym - 101889I Imperial roads (树链剖分维护边权最大值)_第1张图片

 

 

题意:给你一个图,然后Q个询问,每个询问,问强制要求使用某条边的情况下的最小生成树。

 

解题思路:先求最小生成树,然后对于强制要求的边,直接查询树上路径最大值,然后减去这个最大值,再加上要求的边的权值就是答案。

 

直接上树链剖分即可。

 

#include
using namespace std;
const int MAXN=400005;
typedef long long ll;
map,int > mp;
struct edge{
    int u,v,w,next;
}ee[MAXN];
bool cmp(edge a,edge b){
    return a.wsize[son[u]])
                son[u]=v;
        }
    }
}

//求出top和pos,求的过程中,先求重链上的dfs序
void dfs2(int u,int sp){
    top[u]=sp;

    if(son[u]!=-1){
        pos[u]=SEG++;
        dfs2(son[u],sp);
    }
    else{
        pos[u]=SEG++;
        return;
    }

    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(v!=son[u]&&v!=fa[u]){
            dfs2(v,v);
        }
    }

}

//线段树部分
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int MAX[MAXN<<2];
int val[MAXN<<2];
void pushup(int rt){
    MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}

void build(int l,int r,int rt){
    if(l==r){
        MAX[rt]=val[l];
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}

int query(int L,int R,int l,int r,int rt){
    if(l>=L&&r<=R){
        return MAX[rt];
    }
    int m=(l+r)>>1;
    int res=0;
    if(m>=L)
        res=max(res,query(L,R,lson));
    if(R>m)
        res=max(res,query(L,R,rson));
    return res;
}

//线段树+树链剖分部分
int query(int u,int v){
    int f1=top[u],f2=top[v];
    int temp=0;
    while(f1!=f2){
        if(deep[f1]deep[v])
        swap(u,v);
    //cout<

 

你可能感兴趣的:(————ACM相关————,——图论相关——,ACM,-,最小生成树,ACM,-,树链剖分,ACM,-,线段树)