按海拔从大到小合并建出kruskal重构树,这样就能知道开车能到达哪些点,对这些点到1的最短路取min即可。最难的部分在于多组数据的初始化和数组大小的设置。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cassert>
using namespace std;
#define ll long long
#define N 200010
#define M 400010
#define inf 2000000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int T,n,m,p[N],d[N],fa[N<<1],t,cnt;
bool flag[N];
struct data{int to,nxt,len,h;
}edge[M<<1];
void addedge(int x,int y,int z,int h){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,edge[t].h=h,p[x]=t;}
struct data2
{
int x,d;
bool operator <(const data2&a) const
{
return d>a.d;
}
};
struct data3
{
int x,y,z;
bool operator <(const data3&a) const
{
return z>a.z;
}
}e[M];
priority_queue<data2> q;
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void dijkstra()
{
while (!q.empty()) q.pop();q.push((data2){1,0});
for (int i=2;i<=n;i++) d[i]=inf;d[1]=0;
memset(flag,0,sizeof(flag));
for (;;)
{
while (!q.empty()&&flag[q.top().x]) q.pop();
if (q.empty()) break;
data2 x=q.top();q.pop();
flag[x.x]=1;
for (int i=p[x.x];i;i=edge[i].nxt)
if (x.d+edge[i].len<d[edge[i].to])
{
d[edge[i].to]=x.d+edge[i].len;
q.push((data2){edge[i].to,d[edge[i].to]});
}
}
}
namespace kruskal_tree
{
int p[N<<1],t,fa[N<<1][20],val[N<<1],h[N<<1];
struct data{int to,nxt,len;}edge[N<<1];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{
val[k]=k<=n?d[k]:inf;
for (int i=p[k];i;i=edge[i].nxt)
{
fa[edge[i].to][0]=k;
dfs(edge[i].to);
val[k]=min(val[k],val[edge[i].to]);
}
}
void build()
{
fa[cnt][0]=cnt;dfs(cnt);
for (int j=1;j<20;j++)
for (int i=1;i<=cnt;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("return.in","r",stdin);
freopen("return.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();
while (T--)
{
n=read(),m=read();
for (int i=1;i<=n;i++) p[i]=0;t=0;
for (int i=1;i<=m;i++)
{
int x=read(),y=read(),z=read(),h=read();
e[i].x=x,e[i].y=y,e[i].z=h;
addedge(x,y,z,h),addedge(y,x,z,h);
}
dijkstra();
sort(e+1,e+m+1);
for (int i=1;i<=n;i++) fa[i]=i,kruskal_tree::h[i]=inf,kruskal_tree::p[i]=0;cnt=n;kruskal_tree::t=0;
for (int i=1;i<=m;i++)
{
int p=find(e[i].x),q=find(e[i].y);
if (p!=q)
{
cnt++;fa[cnt]=fa[p]=fa[q]=cnt;kruskal_tree::p[cnt]=0;
kruskal_tree::addedge(cnt,p),kruskal_tree::addedge(cnt,q);
kruskal_tree::h[cnt]=e[i].z;
}
}
kruskal_tree::build();
int Q=read(),K=read(),S=read(),ans=0;
while (Q--)
{
int x=(read()+K*ans-1)%n+1,y=(read()+K*ans)%(S+1);
for (int j=19;~j;j--) if (kruskal_tree::h[kruskal_tree::fa[x][j]]>y) x=kruskal_tree::fa[x][j];
printf("%d\n",ans=kruskal_tree::val[x]);
}
}
return 0;
}
来源:https://www.cnblogs.com/Gloid/p/10177207.html