zoukankan      html  css  js  c++  java
  • [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
    ",last);
            }
        }
    }
    
  • 相关阅读:
    C# 生成随机数
    C#经典机试题(猫叫)
    C#开发微信公众平台-就这么简单(附Demo)(转)
    对于初学者文档应该怎么编写呢?使用什么模板或格式?
    c#基础系列(转)
    如何写软件设计文档(转)
    C# 使用线程池,设置每个线程的执行时间,过了时间强制结束
    C#多线程编程总结
    最全的sublime插件整理
    Node.js安装及环境配置之Windows篇
  • 原文地址:https://www.cnblogs.com/lsgjcya/p/9520625.html
Copyright © 2011-2022 走看看