zoukankan      html  css  js  c++  java
  • F. Auction of Services

    F. Auction of Services

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

    构建最小生成树,然后在树上建立lca,对于每次查询,相当于输出任意两点之间的最大值,用lca来处理树上任意两点的最大值。
    g[i][j]表示i号点向上跳2^j次的链上的最大值

    g[now][i]=max(g[now][i],g[f[now][i-1]][i-1]);
    g[now][i]=max(g[now][i],g[now][i-1]);

    ans=max(ans,g[x][0]);
    ans=max(ans,g[y][0]);

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #define inf 2147483647
    #define N 200010
    #define p(a) putchar(a)
    #define For(i,a,b) for(int i=a;i<=b;++i)
    //by war
    //2020.10.13
    using namespace std;
    
    int T,n,m,s,x,y,a,b,k;
    int f[N][21],deep[N],g[N][21],d[N];
    bool flag;
    void in(int &x){
        int y=1;char c=getchar();x=0;
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        x*=y;
    }
    void o(int x){
        if(x<0){p('-');x=-x;}
        if(x>9)o(x/10);
        p(x%10+'0');
    }
    
    struct Node{
        int l;
        int r;
        int v;
        bool operator < (const Node &k) const{
            return v<k.v;
        }
    }E[2*N];
    
    struct node{
        int n;
        int v;
        node *next;
    }*e[2*N];
    
    void push(int x,int y,int v){
        node *p;
        p=new node();
        p->n=y;
        p->v=v;
        if(e[x]==0) e[x]=p;
        else{
            p->next=e[x]->next;
            e[x]->next=p;
        }
    }
    
    void build(int now){
        deep[now]=deep[f[now][0]]+1;
        for(int i=1;(1<<i)<=deep[now];i++){
            f[now][i]=f[f[now][i-1]][i-1];
            g[now][i]=max(g[now][i],g[f[now][i-1]][i-1]);
            g[now][i]=max(g[now][i],g[now][i-1]);
        }
    
        for(node *i=e[now];i!=NULL;i=i->next){
            if(i->n!=f[now][0]){
                f[i->n][0]=now;
                g[i->n][0]=max(i->v,g[i->n][0]);
                build(i->n);
            }
        }
    } 
    
    int query(int x,int y){
        int ans=0;
        if(deep[x]<deep[y]) swap(x,y);
        int c=deep[x]-deep[y];
        for(int i=0;i<=log2(c);i++){
            if((1<<i)&c){
                ans=max(ans,g[x][i]);
                x=f[x][i];
            }
        }
        if(x==y) return ans;
        for(int i=log2(deep[x]);i>=0;i--){
            if(f[x][i]!=f[y][i]){
                ans=max(ans,g[x][i]);
                ans=max(ans,g[y][i]);
                x=f[x][i];
                y=f[y][i];
            }
        }
        ans=max(ans,g[x][0]);
        ans=max(ans,g[y][0]);
        return ans;
    }
    
    int find(int x){
        if(d[x]==x) return x;
        return d[x]=find(d[x]);
    }
    
    signed main(){ 
        in(n);in(m);
        For(i,1,m){
            in(E[i].l);in(E[i].r);in(E[i].v);
        }
        For(i,1,n) d[i]=i;
        sort(E+1,E+m+1);
        For(i,1,m){
            if(find(E[i].l)!=find(E[i].r)){
                d[find(E[i].l)]=find(E[i].r);
                push(E[i].l,E[i].r,E[i].v);
                push(E[i].r,E[i].l,E[i].v);
            }
        }
        f[1][0]=1;
        build(1);
        in(T);
        while(T--){
            in(x);in(y);
            o(query(x,y));p('
    ');
        }
        return 0;
    }
  • 相关阅读:
    KMP模板
    洛谷 [P2701] 巨大的牛棚
    浅谈用极大化思想解决最大子矩阵问题
    洛谷 [P1578] WC2002 奶牛浴场
    洛谷 [P1040]加分二叉树
    洛谷 [P1220] 关路灯
    清北学堂复习笔记
    一些比较实用的网站
    图论模板
    一些应该注意的问题
  • 原文地址:https://www.cnblogs.com/war1111/p/13808528.html
Copyright © 2011-2022 走看看