歸程題解

歸程題解

不知道我是看錯了仍是咋的,html

步行能夠走沒有積水的邊,

這樣接下來他就能夠步行通過有積水的邊c++

我看到這一句話,總覺得只能走有積水的邊,
又屈辱看題解
咳咳,使步行總長最小,咱們能夠考慮預處理出每一個點到1的最短路,
看看車子經過沒積水的邊能到哪些點,輸出最小值,
這怎麼搞?
來一波Kruskal重構樹,
沒學過的能夠看個人這篇博客
已知,能走到最上面的點,它的子樹就都能走到
咱們能夠搜索出子樹內最小的最短路,而後倍增,看最多能走到哪一個點,輸出。
代碼:spa

#include<bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=2e5+6,M=4e5+6;
int n,m,t,Q,K,S,cnt=0,num=0,tot=0;
int cnt2=0,head2[N<<1],fa[N<<1],head[N],tt;
int f[N<<1][21],g[N<<1][21];
ll dis[N<<1],mind[N<<1],t1,t2,ans=0;
struct edge{int nxt,to,w;}e[M<<1],gg[M<<1];
struct xd{
   int i; ll z;
   bool operator < (const xd &a) const {return z>a.z;}
}tmp,nw;
struct que{int x,y,z;}qu[M];
priority_queue<xd> q;
inline void add(int u,int v,int w){e[++cnt].nxt=head[u],e[cnt].to=v,e[cnt].w=w,head[u]=cnt;}
inline void add2(int u,int v,int w){gg[++cnt2].nxt=head2[u],gg[cnt2].to=v,gg[cnt2].w=w,head2[u]=cnt2;}
void dijkstra(){
    memset(dis,0x3f,sizeof(dis)),tmp.i=1,tmp.z=0,dis[1]=0,q.push(tmp);
    while(!q.empty()){
        tmp=q.top(),q.pop(); //cout<<tmp.i<<" "<<tmp.z<<endl;
        if(dis[tmp.i]<tmp.z) continue;
        for(int i=head[tmp.i];i;i=e[i].nxt){
            nw.i=e[i].to,nw.z=tmp.z+e[i].w;
            if(dis[nw.i]>nw.z) dis[nw.i]=nw.z,q.push(nw);
        }
    }
    //for(int i=1;i<=n;++i) printf("%d %lld\n",i,dis[i]);
}
inline int read(){
    int T=0,F=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
    return F*T;
}
bool cmp(que u,que v){return u.z>v.z;}
int getf(int x){return fa[x]==x?x:fa[x]=getf(fa[x]);}
bool merge(int x,int y,int z){
     x=getf(x),y=getf(y);
     if(x==y) return false;
     ++tot,f[x][0]=tot,f[y][0]=tot,g[x][0]=z,g[y][0]=z,fa[x]=fa[y]=fa[tot]=tot,add2(tot,x,z),add2(tot,y,z);
     return true;   
}
void dfs(int x){
    mind[x]=dis[x];
    for(int i=1;i<=20;++i) f[x][i]=f[f[x][i-1]][i-1],g[x][i]=min(g[x][i-1],g[f[x][i-1]][i-1]); 
    for(int i=head2[x];i;i=gg[i].nxt) dfs(gg[i].to),mind[x]=min(mind[x],mind[gg[i].to]);  
}
int main(){
    tt=read();
    while(tt--){
       n=read(),m=read(),cnt=0,cnt2=0,num=0,ans=0,tot=n,memset(dis,0x3f,sizeof(dis)),memset(head,0,sizeof(head)),memset(head2,0,sizeof(head2)),memset(g,0,sizeof(g)),memset(f,0,sizeof(f));
        for(int i=1;i<=n;++i) fa[i]=i;
       for(int i=1;i<=m;++i) qu[i].x=read(),qu[i].y=read(),t=read(),qu[i].z=read(),add(qu[i].x,qu[i].y,t),add(qu[i].y,qu[i].x,t);
       sort(qu+1,qu+m+1,cmp),dijkstra();
       for(int i=1;i<n;++i){
           ++num;
           if(num>m) break;
           if(!merge(qu[num].x,qu[num].y,qu[num].z)) --i;
    } 
        dfs(tot),Q=read(),K=read(),S=read()+1;
    for(int i=1;i<=Q;++i){
           t1=read(),t2=read(),t1=(t1+ans*K-1)%n+1,t2=(t2+ans*K)%S;
           for(int j=20;j>=0;--j) if(f[t1][j]&&t2<g[t1][j]) t1=f[t1][j];
           ans=mind[t1],printf("%lld\n",ans);
       }  
    }   
    return 0;
}
相關文章
相關標籤/搜索