给定一个 n ( ≤ 2 ∗ 1 0 5 ) n(≤2*10^5) n(≤2∗105)个节点、 m ( ≤ 4 ∗ 1 0 5 ) m(≤4*10^5) m(≤4∗105)条边的无向连通图,用 l ( ≤ 1 0 4 ) l(≤10^4) l(≤104), a ( ≤ 1 0 9 ) a(≤10^9) a(≤109)描述一条边的长度、海拔。
给定 Q ( ≤ 4 ∗ 1 0 5 ) Q(≤4*10^5) Q(≤4∗105)天,每天给出出发节点v和水位线p。所有海拔不超过p的边都会被淹。Yazid要回到位于1号节点的家。他在点v有辆车,但不能驶过被淹的边。Yazid 可以在任意节点下车,这样接下来他就可以步行经过有积水的边。但车会被留在他下车的节点并不会再被使用。
求最小的步行经过的边的总长度。部分数据强制在线。有多组数据,但数据组数T≤3。
#include
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
#define clear(a) fo(ii,1,n)a[ii]=0
#define cle(a) memset(a,0,sizeof a)
#define rep(i,x) for(edg *i=x; i; i=i->ne)
#define MIN(x,y) x=min(x,y)
using namespace std;
typedef long long ll;
const int N=4e5+1;
const ll inf=0x7FFFFFFF;
int T,i,n,m,u,v,a,ii,x,y,num,Q,K,S,v0,p0,p;
ll l,ans,dis[N];
struct edge
{
int u,v,a;
ll l;
}e[N];
struct edg
{
int to;
ll l;
edg *ne;
inline edg(int to,ll l,edg *ne) : to(to), l(l), ne(ne){}
}*fin[N];
template <class T> inline void read(T &x)
{
char ch=getchar(); x=0;
for(;!isdigit(ch);ch=getchar());
for(;isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
}
inline void link(int x,int y)
{
fin[x]=new edg(y,l,fin[x]);
}
struct node
{
int i; ll dis;
inline node(int _i,ll _dis){i=_i; dis=_dis;}
};
struct cmp1
{
inline bool operator ()(const node &a,const node &b){return a.dis>b.dis;}
};
priority_queue <node,vector<node>,cmp1> P;
bool vis[N];
void dijkstra()
{
while(!P.empty())P.pop(); P.push(node(1,0));
clear(vis);
memset(dis,127,sizeof dis); dis[1]=0;
while(!P.empty())
{
node t=P.top(); P.pop();
int x=t.i; ll d=t.dis;
if(vis[x]) continue;
vis[x]=1;
rep(i,fin[x])
{
y=i->to; l=i->l;
if(!vis[y]&&dis[y]>d+l)
{
dis[y]=d+l;
P.push(node(y,dis[y]));
}
}
}
}
int fa[N],fu,fv,L[N],R[N],anc[N][18],low[N][18];
ll mi[N];
inline bool cmp(edge a,edge b){return a.a>b.a;}
int gef(int x)
{
return fa[x]==x ? x : fa[x]=gef(fa[x]);
}
void kruskal()
{
sort(e+1,e+m+1,cmp);
cle(anc); cle(low); cle(L); cle(R);
int i;
fo(i,1,n)fa[i]=i;
fo(i,1,m)
{
u=e[i].u; v=e[i].v;
fu=gef(u);fv=gef(v);
if(fu!=fv)
{
anc[fu][0]=fa[fu]=anc[fv][0]=fa[fv]=fa[num+1]=++num;
low[fu][0]=low[fv][0]=e[i].a;
L[num]=fu; R[num]=fv;
}
}
}
void dfs(int x)
{
int i,f=anc[x][0]; mi[x]=dis[x];
fo(i,1,17)
{
if(!f) break;
low[x][i]=low[f][i-1];
f=anc[x][i]=anc[f][i-1];
}
if(L[x]) dfs(L[x]), MIN(mi[x],mi[L[x]]);
if(R[x]) dfs(R[x]), MIN(mi[x],mi[R[x]]);
}
int main()
{
for(read(T);T;T--)
{
read(n); read(m);
clear(fin);
fo(i,1,m)
{
read(u), read(v), read(l), read(a);
e[i].u=u,e[i].v=v,e[i].l=l,e[i].a=a;
link(u,v); link(v,u);
}
dijkstra();
num=n; kruskal();
dfs(num);
read(Q); read(K); read(S); ans=0;
fo(i,1,Q)
{
read(v0); v=(v0+K*ans-1)%n+1;
read(p0); p=(p0+K*ans)%(S+1);
fd(ii,17,0) if( anc[v][ii] && low[v][ii]>p ) v=anc[v][ii];
printf("%lld\n",ans=mi[v]);
}
}
}