zoukankan      html  css  js  c++  java
  • hdu-3078 Network(lca+st算法+dfs)

    题目链接:

    Network

    Time Limit: 2000/1000 MS (Java/Others)   

     Memory Limit: 65536/65536 K (Java/Others)


    Problem Description
     
    The ALPC company is now working on his own network system, which is connecting all N ALPC department. To economize on spending, the backbone network has only one router for each department, and N-1 optical fiber in total to connect all routers.
    The usual way to measure connecting speed is lag, or network latency, referring the time taken for a sent packet of data to be received at the other end.
    Now the network is on trial, and new photonic crystal fibers designed by ALPC42 is trying out, the lag on fibers can be ignored. That means, lag happened when message transport through the router. ALPC42 is trying to change routers to make the network faster, now he want to know that, which router, in any exactly time, between any pair of nodes, the K-th high latency is. He needs your help.
     
    Input
     
    There are only one test case in input file.
    Your program is able to get the information of N routers and N-1 fiber connections from input, and Q questions for two condition: 1. For some reason, the latency of one router changed. 2. Querying the K-th longest lag router between two routers.
    For each data case, two integers N and Q for first line. 0<=N<=80000, 0<=Q<=30000.
    Then n integers in second line refer to the latency of each router in the very beginning.
    Then N-1 lines followed, contains two integers x and y for each, telling there is a fiber connect router x and router y.
    Then q lines followed to describe questions, three numbers k, a, b for each line. If k=0, Telling the latency of router a, Ta changed to b; if k>0, asking the latency of the k-th longest lag router between a and b (include router a and b). 0<=b<100000000.
    A blank line follows after each case.
     
    Output
     
    For each question k>0, print a line to answer the latency time. Once there are less than k routers in the way, print "invalid request!" instead.
     
    Sample Input
     
    5 5
    5 1 2 3 4
    3 1
    2 1
    4 3
    5 3
    2 4 5
    0 1 2
    2 2 3
    2 1 4
    3 3 5
     
    Sample Output
     
    3
    2
    2
    invalid request!
     
    题意:
     
    给一棵树上的每个点的权值和边的连接情况,然后问点l到点r的路径上权值第k大的点,如果k==0,则修改一个点的权值;
     
    思路:
     

    lca的ST算法;求第k大的时候可以把这条路径上的点的权值都保存下来,排序后输出就行,我还担心会不会tle,最后还是AC了;
     
    AC代码:
     
    #include <bits/stdc++.h>
    using namespace std;
    const int N=8e4+4;
    typedef long long ll;
    const double PI=acos(-1.0);
    int n,q,head[N],cnt=1,num=0,dp[2*N][32],first[N],fa[N],vis[N],a[2*N],dep[N],rec[N],va[N];
    struct Edge
    {
        int to,next;
    };
    Edge edge[2*N];
    int cmp(int x,int y)
    {
        return x>y;
    }
    void addedge(int s,int e)
    {
        edge[cnt].to=e;
        edge[cnt].next=head[s];
        head[s]=cnt++;
    }
    int dfs(int x,int deep)
    {
        vis[x]=1;
        a[num]=x;
        dep[x]=deep;
        first[x]=num++;
        for(int i=head[x];i!=-1;i=edge[i].next)
        {
            int y=edge[i].to;
            if(!vis[y])
            {
                fa[y]=x;
                dfs(y,deep+1);
                a[num++]=x;
            }
        }
    }
    void RMQ()
    {
        for(int i=0;i<num;i++)//dp[i][j]表示区间[i,i+2^j-1]内的最小值;ST算法是基于dp的算法;
        {
            dp[i][0]=a[i];
        }
        for(int j=1;(1<<j)<=num;j++)
        {
            for(int i=0;i+(1<<j)-1<num;i++)
            {
                    if(dep[dp[i][j-1]]<dep[dp[i+(1<<(j-1))][j-1]])
                    {
                        dp[i][j]=dp[i][j-1];
                    }
                    else dp[i][j]=dp[i+(1<<(j-1))][j-1];
            }
        }
    }
    int query(int x,int y)
    {
        int temp=(int)(log((y-x+1)*1.0)/log(2.0));
        if(dep[dp[x][temp]]<dep[dp[y-(1<<temp)+1][temp]])return dp[x][temp];
        else return dp[y-(1<<temp)+1][temp];//区间[x,x+2^temp-1]+[y-2*temp+1,y]肯定包含区间[x,y];所以结果是正确的;
    }
    int get_ans(int x,int y,int d)
    {
        int lca;
        if(first[x]<first[y])
        lca=query(first[x],first[y]);
        else lca=query(first[y],first[x]);
        int counter=0;
        rec[counter++]=va[lca];
        while(x!=lca)
        {
            rec[counter++]=va[x];
            x=fa[x];
        }
        while(y!=lca)
        {
            rec[counter++]=va[y];
            y=fa[y];
        }
        if(counter<d)printf("invalid request!
    ");
        else
        {
            sort(rec,rec+counter,cmp);
            printf("%d
    ",rec[d-1]);
        }
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&va[i]);
        }
        int l,r;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&l,&r);
            addedge(l,r);
            addedge(r,l);
        }
        fa[1]=1;
        dfs(1,0);
        RMQ();
        int k,u,v;
        while(q--)
        {
            scanf("%d%d%d",&k,&u,&v);
            if(k==0)va[u]=v;
            else
            {
                get_ans(u,v,k);
            }
        }
        return 0;
    }
     
     
  • 相关阅读:
    论文笔记:语音情感识别(五)语音特征集之eGeMAPS,ComParE,09IS,BoAW
    《Grammar and Punctuation》课堂笔记
    《Sequence Models》课堂笔记
    【翻译】学术写作中的数字
    生成器
    使用序列生成字典
    字典 (dictionary) 的默认值
    如何阅读文献 (How to Read a Paper)
    Python 列表的连接和联合
    《Convolutional Neural Networks》课堂笔记
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5378471.html
Copyright © 2011-2022 走看看