傳送門html
前置技能,克魯斯卡爾重構樹node
咱們按道路的高度建一個最大生成樹,而後建好克魯斯卡爾重構樹ios
那麼咱們須要知道一顆子樹內到1點距離最近是多少(除此以外到子樹內任何一個點都不須要代價)git
能夠一開始直接跑一個dijkstra(關於SPFA,他死了)spa
而後一遍樹形dp就能夠了code
1 //minamoto 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cstdio> 6 #include<queue> 7 using namespace std; 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 9 char buf[1<<21],*p1=buf,*p2=buf; 10 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;} 11 inline int read(){ 12 #define num ch-'0' 13 char ch;bool flag=0;int res; 14 while(!isdigit(ch=getc())) 15 (ch=='-')&&(flag=true); 16 for(res=num;isdigit(ch=getc());res=res*10+num); 17 (flag)&&(res=-res); 18 #undef num 19 return res; 20 } 21 char sr[1<<21],z[20];int C=-1,Z; 22 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 23 inline void print(int x){ 24 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 25 while(z[++Z]=x%10+48,x/=10); 26 while(sr[++C]=z[Z],--Z);sr[++C]='\n'; 27 } 28 const int N=800005; 29 struct EE{ 30 int u,v,h; 31 EE(){} 32 EE(int u,int v,int h):u(u),v(v),h(h){} 33 inline bool operator <(const EE &b)const 34 {return h>b.h;} 35 }E[N]; 36 struct node{ 37 int u,dis; 38 node(){} 39 node(int u,int dis):u(u),dis(dis){} 40 inline bool operator <(const node &b)const 41 {return dis>b.dis;} 42 }; 43 int head[N],Next[N],ver[N],edge[N],tot; 44 int hc[N],nc[N],vc[N],tc; 45 int val[N],f[N][25],fa[N],dis[N],vis[N],mn[N],bin[25]; 46 int n,m,ans,k; 47 priority_queue<node> q; 48 inline void clear(){ 49 memset(head,0,sizeof(head)),tot=0; 50 memset(hc,0,sizeof(hc)),tc=0; 51 memset(mn,0x3f,sizeof(mn)); 52 memset(f,0,sizeof(f)); 53 } 54 inline void add(int u,int v,int e){ 55 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e; 56 } 57 inline void addc(int u,int v){ 58 vc[++tc]=v,nc[tc]=hc[u],hc[u]=tc; 59 } 60 inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} 61 inline void mission(int u){ 62 for(int i=1;bin[i]<=n;++i) 63 f[u][i]=f[f[u][i-1]][i-1]; 64 } 65 void dijkstra(int s=1){ 66 memset(vis,0,sizeof(vis)); 67 memset(dis,0x3f,sizeof(dis)); 68 q.push(node(s,0)),dis[s]=0; 69 while(!q.empty()){ 70 int u=q.top().u;q.pop(); 71 if(vis[u]) continue; 72 vis[u]=1; 73 for(int i=head[u];i;i=Next[i]){ 74 int v=ver[i]; 75 if(cmin(dis[v],dis[u]+edge[i])) q.push(node(v,dis[v])); 76 } 77 } 78 memcpy(mn+1,dis+1,sizeof(int)*(n)); 79 } 80 void dfs(int u){ 81 mission(u); 82 for(int i=hc[u];i;i=nc[i]){ 83 int v=vc[i]; 84 dfs(v),cmin(mn[u],mn[v]); 85 } 86 } 87 inline int query(int u,int x){ 88 for(int i=19;~i;--i) 89 if(f[u][i]&&val[f[u][i]]>x) u=f[u][i]; 90 return mn[u]; 91 } 92 void kruskal(){ 93 int cnt=n; 94 for(int i=1;i<=(n<<1);++i) fa[i]=i; 95 sort(E+1,E+1+m); 96 for(int i=1;i<=m;++i){ 97 int u=find(E[i].u),v=find(E[i].v); 98 if(u!=v){ 99 val[++cnt]=E[i].h; 100 f[u][0]=f[v][0]=cnt,fa[u]=fa[v]=cnt; 101 addc(cnt,u),addc(cnt,v); 102 if(cnt-n==n-1) break; 103 } 104 } 105 dfs(cnt); 106 } 107 int main(){ 108 // freopen("testdata.in","r",stdin); 109 int T=read(); 110 bin[0]=1;for(int i=1;i<=23;++i) bin[i]=bin[i-1]<<1; 111 while(T--){ 112 n=read(),m=read(),ans=0; 113 clear(); 114 for(int i=1,u,v,e,h;i<=m;++i){ 115 u=read(),v=read(),e=read(),h=read(),E[i]=EE(u,v,h); 116 add(u,v,e),add(v,u,e); 117 } 118 dijkstra(); 119 kruskal(); 120 int q=read(),k=read(),s=read(); 121 while(q--){ 122 int u=(k*ans+read()-1)%n+1,v=(k*ans+read())%(s+1); 123 print(ans=query(u,v)); 124 } 125 } 126 Ot(); 127 return 0; 128 }