[NOI2018]归程(kruscal重构树)
[NOI2018]归程
题面太长辣,戳这里
模拟赛上写了一个spfa (关于spfa,它已经死了),然后一个st表水完暴力跑路。考后说是Kruscal重构树或者可持久化并查集???这都是些什么东西。不过还是填一下这个坑。
STO YZK IOI2020捧杯<---学习笔记
然后自己yy写了重构树,感觉代码还算优美??吧
数组又又又又又又又又又开小了,dis数组也要开2*N。
#include<bits/stdc++.h>
#define Min(a,b) (a)<(b)?(a):(b)
#define lll long long
using namespace std;
int read()
{
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
const int N=400010;
int n,m,cnt,x,y,z,c,Q,zyys,s;lll asd,zxc,last;
int head[2*N];
bool vis[N];
int fa[2*N],deep[2*N],f[20][2*N];
lll dp[2*N],dis[N],v[2*N];
struct node{
lll v,to,next,h;
}edge[4*N];
struct Node{
int x,y,v,h;
}a[2*N];
void add(int x,int y,int z,int c)
{
cnt++;edge[cnt].to=y;edge[cnt].v=z;edge[cnt].h=c;
edge[cnt].next=head[x];head[x]=cnt;
}
priority_queue<pair<lll,int> >q;
bool cmp(Node p,Node q){return p.h>q.h;}
int gfa(int x){if(x==fa[x])return x;return fa[x]=gfa(fa[x]);}
void dijkstra()
{
memset(dis,0x3f,sizeof(dis));memset(vis,0,sizeof(vis));
q.push(make_pair(0,1));dis[1]=0;
while(q.size())
{
int u=q.top().second;q.pop();
if(vis[u]==true)continue;vis[u]=1;
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].v)
dis[v]=dis[u]+edge[i].v,q.push(make_pair(-dis[v],v));
}
}
}
void dfs(int k,int father)
{
dp[k]=dis[k];
for(int i=head[k];i;i=edge[i].next)
{
int v=edge[i].to;if(v==father)continue;
deep[v]=deep[k]+1;f[0][v]=k;dfs(v,k);
dp[k]=Min(dp[k],dp[v]);
}
}
void init()
{
for(int i=1;i<=19;i++)for(int j=1;j<=n;j++)
f[i][j]=f[i-1][f[i-1][j]];
}
int lca(int x,lll y)
{
for(int i=19;i>=0;i--)
{
if(v[f[i][x]]>y) x=f[i][x];
}
return x;
}
int main()
{
int t=read();
while(t--)
{
n=read();m=read();int nn=n;
cnt=0;memset(head,0,sizeof(head));
for(int i=1;i<=m;i++)
{
x=read();y=read();z=read();c=read();
add(x,y,z,c);add(y,x,z,c);
a[i].x=x;a[i].y=y;a[i].v=z;a[i].h=c;
}
dijkstra();
cnt=0;memset(head,0,sizeof(head));
for(int i=1;i<=n;i++) fa[i]=i;
sort(a+1,a+1+m,cmp);
for(int i=1;i<=m;i++)
{
int xx=gfa(a[i].x),yy=gfa(a[i].y);
if(xx==yy)continue;
n++;fa[n]=n;fa[xx]=n;fa[yy]=n;v[n]=a[i].h;
add(n,xx,v[n],0);add(xx,n,v[n],0);add(n,yy,v[n],0);add(yy,n,v[n],0);
}
deep[n]=1;dfs(n,0);init();
Q=read();zyys=read();s=read();last=0;
for(int i=1;i<=Q;i++)
{
asd=read();zxc=read();
asd=(asd+zyys*last-1)%nn+1;zxc=(zxc+zyys*last)%(s+1);
last=dp[lca(asd,zxc)];
printf("%lld\n",last);
}
}
}