[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);
        }
    }
}
posted @ 2018-08-22 21:50  Frozen_Heart  阅读(174)  评论(0编辑  收藏  举报