zoukankan      html  css  js  c++  java
  • NOI2018 归程

    题目链接:戳我

    kruskal重构树做法。
    预处理每个点到根的最短路。
    将边从大到小排序,然后建树,建出来的kruskal生成树就是一个小根堆。

    我们尽可能的从当前点向上面跳。(也就是带限制“海拔大于等于p”的树上倍增)
    然后呢,因为是一个小根堆,我们可以免费走到该点子树以内任意一个点,所以我们来一个dfs找出字数内到1最短路最短的答案即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define MAXN 400010
    using namespace std;
    int t,n,m,tt,tt2,Q,K,S,v0,p0,cnt,lastans;
    int dist[MAXN],done[MAXN],head[MAXN<<1],head2[MAXN<<1],fa[MAXN<<1],g[MAXN][22],dep[MAXN];
    struct Line{int u,v,len,h;}line[MAXN];
    struct Node{
        int u,d;
        friend bool operator <(struct Node x,struct Node y)
        {return x.d>y.d;}
    }node[MAXN<<1];
    struct Edge{int nxt,to,dis,hei;}edge[MAXN<<2],e[MAXN<<2];
    struct Node2{int u,v,l,a;}kkk[MAXN<<2];
    inline void add(int from,int to,int dis)
    {
        edge[++tt].nxt=head[from],edge[tt].to=to,edge[tt].dis=dis,head[from]=tt;
    }
    inline void add2(int from,int to){e[++tt2].nxt=head2[from],e[tt2].to=to,head2[from]=tt2;}
    inline bool cmp(struct Line x,struct Line y){return x.h>y.h;}
    inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    inline void dij(int s)
    {
        priority_queue<Node>q;
        memset(done,0,sizeof(done));
        memset(dist,0x3f,sizeof(dist));
        q.push((Node){s,0});dist[s]=0;
        while(!q.empty())
        {
            int u=q.top().u;q.pop();
            if(done[u]) continue;
            done[u]=1;
            for(int i=head[u];i;i=edge[i].nxt)
            {
                int v=edge[i].to;
                if(dist[u]+edge[i].dis<dist[v])
                    dist[v]=dist[u]+edge[i].dis,q.push((Node){v,dist[v]});
            }
        }
        for(int i=1;i<=n;i++) kkk[i].l=dist[i];
    }
    inline void kruskal()
    {
        for(int i=1;i<=n*2;i++) fa[i]=i;
        sort(&line[1],&line[m+1],cmp);
        int tot=0;
        cnt=n;
        for(int i=1;i<=m;i++)
        {
            int u=line[i].u,v=line[i].v;
            int a=find(u),b=find(v);
            if(a!=b) 
            {
                cnt++;
                fa[a]=cnt,fa[b]=cnt,fa[cnt]=cnt;
                //printf("u=%d v=%d a=%d b=%d 长度=%d 海拔=%d cnt=%d
    ",u,v,a,b,line[i].len,line[i].h,cnt);
                add2(cnt,a);add2(cnt,b);
                kkk[cnt].a=line[i].h;
                tot++;
            }
            if(tot==n-1) break;
        }
    }
    inline void dfs(int x,int pre)
    {
        dep[x]=dep[pre]+1;
        g[x][0]=pre;
        for(int i=1;i<=21;i++) g[x][i]=g[g[x][i-1]][i-1];
        for(int i=head2[x];i;i=e[i].nxt)
        {
            int v=e[i].to;
            dfs(v,x);
            kkk[x].l=min(kkk[x].l,kkk[v].l);
        }
    }
    inline int query(int x,int y){
        for(int i=21;i>=0;--i)
            if(dep[x]-(1<<i)>0&&kkk[g[x][i]].a>y)
                x=g[x][i];
        return kkk[x].l;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d",&t);
        while(t--)
        {
            memset(fa,0,sizeof(fa));
            memset(head,0,sizeof(head));
            memset(head2,0,sizeof(head2));
            tt=tt2=lastans=0;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++) 
            {   
                scanf("%d%d%d%d",&line[i].u,&line[i].v,&line[i].len,&line[i].h);
                add(line[i].u,line[i].v,line[i].len),add(line[i].v,line[i].u,line[i].len);
            }
            for(int i=n+1;i<=2*n;i++) kkk[i].l=0x3f3f3f3f;
            dij(1);
            kruskal();
            dfs(cnt,0);
            scanf("%d%d%d",&Q,&K,&S);
            for(int i=1;i<=Q;i++)
            {
                scanf("%d%d",&v0,&p0);
                int v=(v0+K*lastans-1)%n+1;
                int p=(p0+K*lastans)%(S+1);
                lastans=query(v,p);
                printf("%d
    ",lastans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    我爱Java系列之---【SpringBoot打成war包部署】
    279. Perfect Squares
    矩阵dfs--走回路
    112. Path Sum
    542. 01 Matrix
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    Invert Binary Tree
    563 Binary Tree Tilt
    145 Binary Tree Postorder Traversal
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10359135.html
Copyright © 2011-2022 走看看