• p4768 [NOI2018]归程


    分析

    先求出每个点到终点的最短路

    我们按照海拔从大到小排序

    然后求出kruskal重构树

    每次答案就是一个可行子树中的最短路的最小值

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define mp make_pair
    #define li long long
    int head[800100],nxt[800100],to[800100],w[800100],n,m,cnt;
    int dis[800100],vis[800100],tot,pr[800100][23],fa[800100],val[800100];
    vector<int>v[800100];
    struct node {
        int x,y,z,w;
    };
    node d[400100];
    inline bool cmp(const node x,const node y){return x.w>y.w;}
    inline int sf(int x){return fa[x]==x?x:fa[x]=sf(fa[x]);}
    struct Kruskal_Tree {
        inline void build(){
          int i,j,k=0;
          for(i=1;i<=n+m;i++)v[i].clear();
          tot=n;sort(d+1,d+m+1,cmp);
          for(i=1;i<=n+m;i++)fa[i]=i;
          for(i=1;i<=m;i++){
              int x=d[i].x,y=d[i].y,z=d[i].w;
              if(sf(x)!=sf(y)){
                v[++tot].push_back(sf(x));
                v[tot].push_back(sf(y));
                fa[sf(x)]=fa[sf(y)]=tot;
                val[tot]=z;
                k++;
            }
            if(k==n-1)break;
          }
        }
        inline void dfs(int x,int fa){
          pr[x][0]=fa;
          for(int i=0;i<v[x].size();i++)
            if(v[x][i]!=fa){
              dfs(v[x][i],x);
              dis[x]=min(dis[x],dis[v[x][i]]);
            }
        }
        inline void deal(){
          for(int i=1;i<=20;i++)
            for(int j=1;j<=tot;j++)
              pr[j][i]=pr[pr[j][i-1]][i-1];
        }
        inline int que(int x,int y){
          for(int i=20;i>=0;i--)if(pr[x][i]&&val[pr[x][i]]>y)x=pr[x][i];
          return x;
        }
    };
    Kruskal_Tree T;
    priority_queue<pair<int,int> >q;
    inline void init(){
        cnt=0;
        memset(head,0,sizeof(head));
        memset(dis,0x7f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        memset(pr,0,sizeof(pr));
    }
    inline void add(int x,int y,int z){
        nxt[++cnt]=head[x];
        head[x]=cnt;
        to[cnt]=y;
        w[cnt]=z;
        nxt[++cnt]=head[y];
        head[y]=cnt;
        to[cnt]=x;
        w[cnt]=z;
    }
    inline void dij(){
        dis[1]=0;
        q.push(mp(0,1));
        while(!q.empty()){
          int x=q.top().se;
          q.pop();
          if(vis[x])continue;
          vis[x]=1;
          for(int i=head[x];i;i=nxt[i]){
            if(dis[to[i]]>(li)(dis[x]+w[i])){
              dis[to[i]]=dis[x]+w[i];
              q.push(mp(-dis[to[i]],to[i]));
            }
          }
        }
    }
    int main(){
        int i,j,k,t,x,y,z,q,s;
        scanf("%d",&t);
        while(t--){
          init();
          scanf("%d%d",&n,&m);
          for(i=1;i<=m;i++){
              scanf("%d%d%d%d",&d[i].x,&d[i].y,&d[i].z,&d[i].w);
              add(d[i].x,d[i].y,d[i].z);
          }
          dij();
          T.build();
          T.dfs(tot,0);
          T.deal();
          int lastans=0;
          scanf("%d%d%d",&q,&k,&s);
          while(q--){
              scanf("%d%d",&x,&y);
              x=(x+1ll*k*lastans%n-1)%n+1;
              y=(y+1ll*k*lastans%(s+1))%(s+1);
              lastans=dis[T.que(x,y)];
              printf("%d
    ",lastans);
          }
        }
        return 0;
    }
  • 相关阅读:
    hystrix基本介绍和使用(1)
    Java SPI机制用法demo
    python数据结构与算法——图的最短路径(Bellman-Ford算法)解决负权边
    python数据结构与算法——图的最短路径(Dijkstra算法)
    python数据结构与算法——图的最短路径(Floyd-Warshall算法)
    python数据结构与算法——图的广度优先和深度优先的算法
    python数据结构与算法——小猫钓鱼(使用队列)
    python数据结构与算法——栈
    python数据结构与算法——队列
    python数据结构与算法——链表
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/11547136.html
Copyright © 2020-2023  润新知