#Kruskal reconstruction tree, Dijkstra, doubled # Luo Gu 4768 [NOI2018] Return Journey

Topic Portal


analysis

First, \ (\ text {Dijkstra} \ ) is required (about \ (\ text the SPFA} {\) , which die 233)
undirected graph, the first node 1 to determine the distance of all points, and then must hope One can drive to the start point from the shortest to the place where the car can be
, but how to do, considering the large side elevation will certainly be more likely to choose, why not build a Kruskal a maximum spanning tree
but how to find it, \ (\ text {Kruskal reconstructed tree} \) turned out, by connecting the two with the new original point, built a \ (2n-1 \) tree points
that What is the use, the tree becomes a binary stack, in this problem or small roots heap, i.e. two sides of the LCA represents the minimum path tree reconstructed
side and then seek a minimum value not to be solved yet by doubling


Code

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define rr register
using namespace std;
const int N=400011;
struct rec{int x,y,w,c;}T[N]; struct node{int y,w,next;}e[N<<1]; struct Node{int y,next;}E[N];
int ls[N>>1],hs[N],dis[N],h[N],dep[N],n,m,k,K,cnt,nnt,f[N][20],Q,opt,S,fat[N]; pair<int,int>heap[N>>1];
inline signed iut(){
    rr int ans=0; rr char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
    return ans;
}
inline void add(int x,int y,int w){e[++k]=(node){y,w,ls[x]}; ls[x]=k;}
inline void Add(int x,int y){E[++K]=(Node){y,hs[x]},hs[x]=K;}
inline void print(int ans){
    if (ans>9) print(ans/10);
    putchar(ans%10+48);
}
inline void Push(pair<int,int>w){
    heap[++cnt]=w;
    rr int x=cnt;
    while (x>1){
        if (heap[x>>1]>heap[x])
            swap(heap[x>>1],heap[x]),x>>=1;
        else return;
    }
}
inline void Pop(){
    heap[1]=heap[cnt--];
    rr int x=1;
    while ((x<<1)<=cnt){
        rr int y=x<<1;
        if (y<cnt&&heap[y+1]<heap[y]) ++y;
        if (heap[y]<heap[x]) swap(heap[y],heap[x]),x=y;
            else return;
    }
}
inline void Dijkstra(){
    dis[1]=0,heap[++cnt]=make_pair(0,1);
    while (cnt){
        rr int x=heap[1].second,t=heap[1].first;
        Pop(); if (t!=dis[x]) continue;
        for (rr int i=ls[x];i;i=e[i].next)
        if (dis[e[i].y]>dis[x]+e[i].w){
            dis[e[i].y]=dis[x]+e[i].w;
            Push(make_pair(dis[e[i].y],e[i].y));
        }
    }
}
bool cmp(rec x,rec y){return x.c>y.c;}
inline signed getf(int u){return fat[u]==u?u:fat[u]=getf(fat[u]);}
inline void Kruskal(){
    for (rr int i=1;i<n*2;++i) fat[i]=i;
    for (rr int i=1,tot=0;i<=m;++i){
        rr int fa=getf(T[i].x),fb=getf(T[i].y);
        if (fa!=fb){
            fat[fa]=fat[fb]=++nnt,h[nnt]=T[i].c;
            Add(nnt,fa),Add(nnt,fb);
            if (++tot==n-1) return;
        }
    }
}
inline void dfs(int x,int fa){
    dep[x]=dep[fa]+1,f[x][0]=fa;
    for (rr int i=1;i<20;++i) f[x][i]=f[f[x][i-1]][i-1];
    for (rr int i=hs[x];i;i=E[i].next)
        dfs(E[i].y,x),dis[x]=min(dis[x],dis[E[i].y]);
}
inline signed GetF(int x,int H){
    for (rr int i=19;~i;--i)
    if (dep[x]>=(1<<i)&&h[f[x][i]]>H) x=f[x][i];
    return dis[x];
}
signed main(){
    for (rr int Test=iut();Test;--Test){
        memset(ls,0,sizeof(ls)),memset(f,0,sizeof(f));
        memset(dep,0,sizeof(dep)),memset(hs,0,sizeof(hs));
        memset(h,0,sizeof(h)),memset(dis,0x3f,sizeof(dis));
        n=iut(),m=iut(),k=K=1,nnt=n;
        for (rr int i=1;i<=m;++i){
            T[i]=(rec){iut(),iut(),iut(),iut()};
            add(T[i].x,T[i].y,T[i].w);
            add(T[i].y,T[i].x,T[i].w);
        }
        Dijkstra(),sort(T+1,T+1+m,cmp),Kruskal(),
        dfs(nnt,0),Q=iut(),opt=iut(),S=iut();
        for (rr int lastans=0;Q;Q--){
            rr int G=iut(),H=iut();
            if (opt) G=(G+lastans-1)%n+1,H=(H+lastans)%(S+1);
            print(lastans=GetF(G,H)),putchar(10);
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Spare-No-Effort/p/12355085.html