给一个图,每次询问从某个点出发,先坐车经过一些权值大于 p p 的边,然后下车走到1,问走的最短距离,强制在线。
蒟蒻选手没有去noi,听说这是道签到题,看下能否成功签到。
因为知道是kruskal重构树所以就成功签到了啦啦啦。
建出最大kruskal重构树,因为重构树上的点的点权是由根至叶子递增的,倍增找到那个点,其子树就是起始点出发能到的点,dij预处理即可。
多组数据忘了初始化幸好不在现场
code:
#include
#include
#include
#include
#include
#include
#define LL long long
using namespace std;
const LL inf=1LL<<60;
struct Node{
LL x,y,c,a,next;
}e[400010],a[800010];LL len=0,last[200010];
LL Fa[400010],c[400010],dep[400010],fa[400010][22],son[400010][2];
LL dis[200010],root,p,v,Min[400010];
bool vis[200010];
struct node{
LL x,d;
node() {}
node(LL a,LL b) {x=a;d=b;}
};
bool operator < (node a,node b) {return a.d>b.d;}
LL n,m,Q,K,S;
LL findfa(LL x) {return Fa[x]==x?x:Fa[x]=findfa(Fa[x]);}
void ins(LL x,LL y,LL c)
{
a[++len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len;
}
priority_queue q;
void dij()
{
memset(vis,false,sizeof(vis));
for(LL i=1;i<=n;i++) dis[i]=inf;dis[1]=0;
q.push(node(1,0));
while(!q.empty())
{
node t=q.top();q.pop();LL x=t.x;
if(vis[x]) continue;vis[x]=true;
for(LL i=last[x];i;i=a[i].next)
{
LL y=a[i].y;
if(dis[y]>dis[x]+a[i].c) dis[y]=dis[x]+a[i].c,q.push(node(y,dis[y]));
}
}
}
bool cmp(Node a,Node b) {return a.a>b.a;}
void dfs(LL x,LL f)
{
dep[x]=dep[f]+1;fa[x][0]=f;
for(LL i=1;(1<1]][i-1];
if(son[x][0])
{
dfs(son[x][0],x);dfs(son[x][1],x);
Min[x]=min(Min[son[x][0]],Min[son[x][1]]);
}
else Min[x]=dis[x];
}
LL ans=0;
void solve(LL x)
{
for(LL i=20;i>=0;i--)
if((1<p) x=fa[x][i];
ans=Min[x];printf("%lld\n",Min[x]);
}
int main()
{
//freopen("return.in","r",stdin);
//freopen("return.out","w",stdout);
LL T;scanf("%lld",&T);
while(T--)
{
scanf("%lld %lld",&n,&m);root=n;
for(LL i=1;i<=2*n;i++) Fa[i]=i;
len=0;memset(last,0,sizeof(last));
memset(son,0,sizeof(son));
memset(fa,0,sizeof(fa));
for(LL i=1;i<=m;i++)
{
LL x,y,l,k;scanf("%lld %lld %lld %lld",&x,&y,&l,&k);
e[i].x=x;e[i].y=y;e[i].c=l;e[i].a=k;
ins(x,y,l);ins(y,x,l);
}
dij();
sort(e+1,e+m+1,cmp);
for(LL i=1;i<=m;i++)
{
LL tx=findfa(e[i].x),ty=findfa(e[i].y);
if(tx==ty) continue;
Fa[tx]=Fa[ty]=++root;c[root]=e[i].a;
son[root][0]=tx;son[root][1]=ty;
}
dep[0]=-1;dfs(root,0);ans=0;
scanf("%lld %lld %lld",&Q,&K,&S);
while(Q--)
{
scanf("%lld %lld",&v,&p);
v=(v+K*ans-1)%n+1;p=(p+K*ans)%(S+1);
solve(v);
}
}
}