传送门

前置技能,克鲁斯卡尔重构树

我们按道路的高度建一个最大生成树,然后建好克鲁斯卡尔重构树

那么我们需要知道一颗子树内到1点距离最近是多少(除此之外到子树内任何一个点都不需要代价)

可以一开始直接跑一个dijkstra(关于SPFA,他死了)

然后一遍树形dp就可以了

 //minamoto
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=;
struct EE{
int u,v,h;
EE(){}
EE(int u,int v,int h):u(u),v(v),h(h){}
inline bool operator <(const EE &b)const
{return h>b.h;}
}E[N];
struct node{
int u,dis;
node(){}
node(int u,int dis):u(u),dis(dis){}
inline bool operator <(const node &b)const
{return dis>b.dis;}
};
int head[N],Next[N],ver[N],edge[N],tot;
int hc[N],nc[N],vc[N],tc;
int val[N],f[N][],fa[N],dis[N],vis[N],mn[N],bin[];
int n,m,ans,k;
priority_queue<node> q;
inline void clear(){
memset(head,,sizeof(head)),tot=;
memset(hc,,sizeof(hc)),tc=;
memset(mn,0x3f,sizeof(mn));
memset(f,,sizeof(f));
}
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
}
inline void addc(int u,int v){
vc[++tc]=v,nc[tc]=hc[u],hc[u]=tc;
}
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void mission(int u){
for(int i=;bin[i]<=n;++i)
f[u][i]=f[f[u][i-]][i-];
}
void dijkstra(int s=){
memset(vis,,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
q.push(node(s,)),dis[s]=;
while(!q.empty()){
int u=q.top().u;q.pop();
if(vis[u]) continue;
vis[u]=;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(cmin(dis[v],dis[u]+edge[i])) q.push(node(v,dis[v]));
}
}
memcpy(mn+,dis+,sizeof(int)*(n));
}
void dfs(int u){
mission(u);
for(int i=hc[u];i;i=nc[i]){
int v=vc[i];
dfs(v),cmin(mn[u],mn[v]);
}
}
inline int query(int u,int x){
for(int i=;~i;--i)
if(f[u][i]&&val[f[u][i]]>x) u=f[u][i];
return mn[u];
}
void kruskal(){
int cnt=n;
for(int i=;i<=(n<<);++i) fa[i]=i;
sort(E+,E++m);
for(int i=;i<=m;++i){
int u=find(E[i].u),v=find(E[i].v);
if(u!=v){
val[++cnt]=E[i].h;
f[u][]=f[v][]=cnt,fa[u]=fa[v]=cnt;
addc(cnt,u),addc(cnt,v);
if(cnt-n==n-) break;
}
}
dfs(cnt);
}
int main(){
// freopen("testdata.in","r",stdin);
int T=read();
bin[]=;for(int i=;i<=;++i) bin[i]=bin[i-]<<;
while(T--){
n=read(),m=read(),ans=;
clear();
for(int i=,u,v,e,h;i<=m;++i){
u=read(),v=read(),e=read(),h=read(),E[i]=EE(u,v,h);
add(u,v,e),add(v,u,e);
}
dijkstra();
kruskal();
int q=read(),k=read(),s=read();
while(q--){
int u=(k*ans+read()-)%n+,v=(k*ans+read())%(s+);
print(ans=query(u,v));
}
}
Ot();
return ;
}

最新文章

  1. C++:通过gethostbyname函数,根据服务器的域名,获取服务器IP
  2. CCNA第三章子网划分,变长子网掩码(VLSM)和TCP/IP排错考试要点学习笔记
  3. Web.config配置文件详解(新手必看)(转)
  4. iOS -数据库网络之xml解析之远程解析XML
  5. object-c cocos2d-x 写程序时注意调试的技巧
  6. J2EE分布式事务中的提交、回滚方法调用异常。
  7. AndroidSDK无法下载API包的解决方法
  8. httpClient 入门实例
  9. no appropriate service handler found The Connection descriptor used by the client was: localhost:1521:myorcl
  10. mpi冒泡排序并行化
  11. codeforces C. Little Pony and Expected Maximum
  12. $.cookie(&#39;name&#39;, null) 删除cookie 失效问题
  13. 宏定义 button 方法 --备
  14. ipset高大上性能果断将nf-HiPac逼下课
  15. new File()
  16. ACM FatMouse&#39; Trade
  17. Spring MVC 使用介绍(六)—— 注解式控制器(二):请求映射与参数绑定
  18. Object:所有类的超类
  19. javaweb简单登陆例子
  20. [https][ssl] keyless SSL

热门文章

  1. MySQL——函数
  2. Java基础教程:对象比较排序
  3. File.basename
  4. js 事件委托 bug 修复
  5. stm32.cube介绍
  6. CodeForces - 922E Birds —— DP
  7. Servlet_03_部署描述符
  8. Promise 入门与使用
  9. PS 滤镜— —球面化效果
  10. bzoj 4032 [ HEOI 2015 ] 最短不公共子串 —— 后缀自动机+序列自动机