首页 > 代码库 > codevs 1519 过路费 最小生成树+倍增

codevs 1519 过路费 最小生成树+倍增

/*codevs 1519 过路费 最小生成树+倍增*/#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxn 100010#define inf 0x3f3f3f3using namespace std;int n,m,q,num,head[maxn],fa[maxn][25],mx[maxn][25],c[maxn],father[maxn];struct node{    int v,t,pre;}e[maxn*2];struct edge{    int u,v,t;    bool operator < (const edge &x) const {        return t<x.t;    }}p[maxn];int init(){    int x=0,f=1;char s=getchar();    while(s<0||s>9){if(s==-)f=-1;s=getchar();}    while(s>=0&&s<=9){x=x*10+s-0;s=getchar();}    return x*f;}int max(int x,int y){    return x>y?x:y;}void swap(int &x,int &y){    int z=x;x=y;y=z;}int find(int x){    if(father[x]!=x)father[x]=find(father[x]);    return father[x];}void Add(int from,int to,int dis){    num++;e[num].v=to;    e[num].t=dis;    e[num].pre=head[from];    head[from]=num;}void Dfs(int now,int from,int dep,int D){    fa[now][0]=from;c[now]=dep;mx[now][0]=D;    for(int i=head[now];i;i=e[i].pre){        int v=e[i].v;        if(v==from)continue;        Dfs(v,now,dep+1,e[i].t);    }}void Get_fa(){    for(int j=1;j<=20;j++)        for(int i=1;i<=n;i++){            fa[i][j]=fa[fa[i][j-1]][j-1];            mx[i][j]=max(mx[i][j-1],mx[fa[i][j-1]][j-1]);        }}int LCA(int a,int b){    int ret=0;    if(c[a]<c[b])swap(a,b);    int t=c[a]-c[b];    for(int i=0;i<=20;i++)        if(t&(1<<i)){            ret=max(ret,mx[a][i]);            a=fa[a][i];        }    if(a==b)return ret;    for(int i=20;i>=0;i--)        if(fa[a][i]!=fa[b][i]){            ret=max(ret,mx[a][i]);            ret=max(ret,mx[b][i]);            a=fa[a][i];b=fa[b][i];        }    ret=max(ret,mx[a][0]);//是mx不是fa!!     ret=max(ret,mx[b][0]);     return ret;}int main(){    n=init();m=init();    int u,v,t;    for(int i=1;i<=n;i++)        father[i]=i;    for(int i=1;i<=m;i++){        p[i].u=init();p[i].v=init();p[i].t=init();    }    sort(p+1,p+1+m);    int tot=0;    for(int i=1;i<=m;i++){        int r1=find(p[i].u);        int r2=find(p[i].v);        if(r1!=r2){            father[r2]=r1;tot++;            Add(p[i].u,p[i].v,p[i].t);            Add(p[i].v,p[i].u,p[i].t);        }        if(tot==n-1)break;    }    Dfs(1,0,0,0);Get_fa();    q=init();    while(q--){        u=init();v=init();        t=LCA(u,v);        printf("%d\n",t);    }    return 0;}

 

codevs 1519 过路费 最小生成树+倍增