传送门

kruskal重构树:

kruskal合并两个联通块时合并的边一定是联通块中权值最大的边,小于等于这条边的边所能联通的所有点在这个联通块中。

在合并两个联通块的时候新建一个点作为两个联通块代表点的父亲,权值为这条合并的边,那么从一个点x往上跳到最靠上的权值小于等于v的祖先,这个祖先的所有叶子节点就是从x走小于等于v的边能到达的点的集合。

所以这题以1为起点跑dijkstra找单源最短路,然后按权值从大到小排序kruskal重构树即可。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#define Formylove return 0
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define inf 1e18
const int N=;
typedef long long LL;
typedef double db;
using namespace std;
int T,n,m,Q,K,S; template<typename T> void read(T &x) {
char ch=getchar(); T f=; x=;
while((ch!='-')&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct edge {
int u,v,l,a;
edge(){}
edge(int u,int v,int a):u(u),v(v),a(a){}
friend bool operator <(const edge&A,const edge&B) {
return A.a>B.a;
}
}e[N]; int ec,fir[N],nxt[N],to[N],val[N];
void add(int u,int v,int w) {
nxt[++ec]=fir[u]; fir[u]=ec; to[ec]=v; val[ec]=w;
nxt[++ec]=fir[v]; fir[v]=ec; to[ec]=u; val[ec]=w;
} int fa[N];
int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } int f[N][],vv[N]; int ec2,fi[N],nx[N],tt[N];
void ADD(int u,int v) {
nx[++ec2]=fi[u]; fi[u]=ec2; tt[ec2]=v;
} LL fans[N],dis[N];
void dfs(int x,int F) {
f[x][]=F;
fans[x]=inf;
if(x<=n) fans[x]=dis[x];
For(i,,) f[x][i]=f[f[x][i-]][i-];
for(int i=fi[x];i;i=nx[i]) {
dfs(tt[i],x);
fans[x]=min(fans[x],fans[tt[i]]);
}
} int totnode;
void kruskal(int n) {
sort(e+,e+m+);
totnode=n;
For(i,,n*) fa[i]=i;
For(i,,m) {
int x=e[i].u,y=e[i].v;
int fx=find(x),fy=find(y);
if(fx!=fy) {
totnode++;
vv[totnode]=e[i].a;
ADD(totnode,fx); ADD(totnode,fy);
fa[fx]=fa[fy]=totnode;
}
}
dfs(totnode,);
} struct node {
int u; LL d;
node(int u,LL d):u(u),d(d){}
friend bool operator <(const node&A,const node&B) {
return A.d>B.d;
}
}; priority_queue<node>que;
int vis[N];
void dijkstra(int s) {
For(i,,n) dis[i]=inf,vis[i]=;
dis[s]=;
que.push(node(s,));
while(!que.empty()) {
node tp=que.top();
que.pop();
if(vis[tp.u]||dis[tp.u]!=tp.d) continue;
vis[tp.u]=;
for(int i=fir[tp.u];i;i=nxt[i]) {
int y=to[i];
if(dis[y]>dis[tp.u]+val[i]) {
dis[y]=dis[tp.u]+val[i];
que.push(node(y,dis[y]));
}
}
}
} void init() {
ec=ec2=;
memset(fir,,sizeof(fir));
memset(fi,,sizeof(fi));
} int main() {
#ifdef ANS
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
read(T);
while(T--) {
init();
read(n); read(m);
For(i,,m) {
int u,v,l,a;
read(u); read(v); read(l); read(a);
add(u,v,l);
e[i]=edge(u,v,a);
}
dijkstra();
kruskal(n);
read(Q); read(K); read(S);
LL ans=;
while(Q--) {
int v0,p0;
read(v0); read(p0);
int x=(v0+ans%n*K%n-)%n+;
int p=(p0+ans%(S+)*K%(S+))%(S+);
Rep(i,,) if(f[x][i]&&vv[f[x][i]]>p)
x=f[x][i];
ans=fans[x];
printf("%lld\n",ans);
}
}
Formylove;
}

最新文章

  1. Linux下显示IP地理位置信息的小工具-nali
  2. 利用iframe将div放置在object的上面
  3. 【BZOJ】【2765】【JLOI2010】铁人双项比赛
  4. Class
  5. 磁盘性能指标--IOPS 理论
  6. mahout分类
  7. ASP.NET中的Request和Respone对象的使用
  8. 201521123118《java程序与设计》第6周学习总结
  9. 基于 HTML5 Canvas 的简易 2D 3D 编辑器
  10. JavaScript(二)
  11. 为SNP增加种族人群频率
  12. Java中的split函数拆分后变成null的问题
  13. 网络编程基础【day09】:实现简单地ssh(四)
  14. Linux 端口信息查看
  15. hihocoder 1638:多级并查集
  16. Vagrant (1) —— 基本安装与配置(上)
  17. String path = request.getContextPath
  18. Jquery 获取Checkbox值,prop 和 attr 函数区别
  19. mysql中sql语句中常见的group_concat()函数意思以及用法,oracle中与其一样的功能函数是wmsys.wm_concat()
  20. Linux crontab命令 定时任务 用法详解以及no crontab for root解决办法

热门文章

  1. Eclipse导入的Maven项目没有Build Path
  2. docker包含哪些内容(1)
  3. C#网页数据采集(三)HttpWebRequest
  4. sklearn中standardscaler中fit_transform()和transform()有什么区别,应该怎么使用?
  5. (3)centos7 目录结构
  6. python之lambda,random,timeit,collections,
  7. 12、testng.xml指定运行测试包、测试类、测试方法
  8. 【android】获取本机ip地址
  9. 剑指offer——68队列的最大值
  10. window_mysql踩坑