zoukankan      html  css  js  c++  java
  • NOI Day1T1归程(Kruskal重构树+Dijkstra)

    NOI Day1T1归程(Kruskal重构树+Dijkstra)

    题目

    洛谷题目传送门

    题解

    其实我不想写......,所以......
    挖个坑......我以后一定会补的
    luogu的题解讲的还是很详细的......
    恩,感谢cwen详细教我做这道题,让我2遍A
    然后我丑陋的代码(代码太长,所以压得很丑)

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iomanip>
    #include<algorithm>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<vector>
    #define rg register
    #define il inline
    #define lst long long
    #define ldb long double
    #define N 400050
    #define M 800050
    using namespace std;
    const lst Inf=1e16;
    il int read()
    {
        rg int s=0,m=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')m=1;ch=getchar();}
        while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
        return m?-s:s;
    }
    
    int n,m,Q,K,S,u,p;
    int cnt,tot;
    lst ans;
    int hd[N],fa[N];
    lst dis[N],tr_dis[N];
    lst f[N][25],g[N][25];
    struct WAY{int u,v;lst w,h;}edge[M];
    struct EDGE{int to,nxt;lst v,h;}ljl[M<<1];
    il int operator<(rg const WAY &a,rg const WAY &b){return a.h>b.h;}
    
    il void memt()
    {
        cnt=0;
        memset(hd,0,sizeof(hd));
        memset(ljl,0,sizeof(ljl));
    }
    il void add(rg int p,rg int q,rg int o,rg int hi){ljl[++cnt]=(EDGE){q,hd[p],o,hi},hd[p]=cnt;}
    int vis[N];
    struct hh{lst D;int id;};
    bool operator<(rg const hh &a,rg const hh &b){return a.D>b.D;}
    priority_queue <hh> H;
    il void Dijkstra()
    {
        for(rg int i=1;i<=n;++i)vis[i]=0,dis[i]=Inf;
        dis[1]=0,H.push((hh){0,1});
        while(!H.empty())
        {
            rg hh S=H.top();H.pop();
            rg int now=S.id;
            if(vis[now])continue;
            vis[now]=1;
            for(rg int i=hd[now];i;i=ljl[i].nxt)
            {
                rg int qw=ljl[i].to;
                if(dis[qw]>dis[now]+ljl[i].v)
                {
                    dis[qw]=dis[now]+ljl[i].v;
                    H.push((hh){dis[qw],qw});
                }
            }
        }
    }
    int find_fa(rg int now)
    {
        if(fa[now]==now)return now;
        return fa[now]=find_fa(fa[now]);
    }
    il void Kruskal()
    {
        rg int nn=2*n;tot=n;
        for(rg int i=1;i<=nn;++i)fa[i]=i;
        sort(edge+1,edge+m+1);
        for(rg int i=1;i<=m;++i)
        {
            rg int u=edge[i].u,v=edge[i].v;
            rg int fx=find_fa(u),fy=find_fa(v);
            if(fx!=fy)
            {
                tot++;
                add(tot,fx,0,edge[i].h);
                add(tot,fy,0,edge[i].h);
                fa[fx]=fa[fy]=tot;
                if(tot==nn-1)break;
            }
        }
    }
    
    void dfs(rg int now,rg int fm,rg lst up)
    {
        f[now][0]=fm,g[now][0]=up;
        for(rg int j=1;j<=20;++j)
        {
            f[now][j]=f[f[now][j-1]][j-1];
            g[now][j]=min(g[now][j-1],g[f[now][j-1]][j-1]);
        }
        for(rg int i=hd[now];i;i=ljl[i].nxt)
        {
            rg int qw=ljl[i].to;
            if(qw!=fm)
                dfs(qw,now,ljl[i].h);
            tr_dis[now]=min(tr_dis[qw],tr_dis[now]);
        }
    }
    
    int main()
    {
        for(rg int T=read();T;T--)
        {
            memt();
            n=read(),m=read();
            for(rg int i=1;i<=m;++i)
            {
                rg int p=read(),q=read(),o=read(),hi=read();
                add(p,q,o,hi),add(q,p,o,hi);
                edge[i]=(WAY){p,q,o,hi};
            }
            Dijkstra(),memt();
            Kruskal();
            for(rg int i=1;i<=n;++i)tr_dis[i]=dis[i];
            for(rg int i=n+1;i<=tot;++i)tr_dis[i]=Inf;
            dfs(tot,0,0);
            ans=0;
            Q=read(),K=read(),S=read();
            while(Q--)
            {
                u=read(),p=read();
                u=(u+K*ans-1)%n+1;
                p=(p+K*ans)%(S+1);
                for(rg int j=19;j>=0;--j)
                    if(g[u][j]>p)u=f[u][j];
                ans=tr_dis[u];
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    scnner02 (nextLine)
    Scanner01
    Spring 框架 (初学)
    查询自己写了多少行代码
    jdbc事务
    jdbc(预编译插入数据)
    jdbc(java连接数据库)
    监听器扩展
    listener(监听器)
    Filter过滤器
  • 原文地址:https://www.cnblogs.com/cjoierljl/p/9391710.html
Copyright © 2011-2022 走看看