• luoguP4768 [NOI2018]归程


    传送门

    kruskal重构树:

    kruskal合并两个联通块时合并的边一定是联通块中权值最大的边,小于等于这条边的边所能联通的所有点在这个联通块中。

    在合并两个联通块的时候新建一个点作为两个联通块代表点的父亲,权值为这条合并的边,那么从一个点x往上跳到最靠上的权值小于等于v的祖先,这个祖先的所有叶子节点就是从x走小于等于v的边能到达的点的集合。

    所以这题以1为起点跑dijkstra找单源最短路,然后按权值从大到小排序kruskal重构树即可。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<set>
    #define Formylove return 0
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    #define inf 1e18
    const int N=1000007; 
    typedef long long LL;
    typedef double db;
    using namespace std;
    int T,n,m,Q,K,S;
    
    template<typename T> void read(T &x) {
        char ch=getchar(); T f=1; x=0;
        while((ch!='-')&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct edge {
        int u,v,l,a;
        edge(){}
        edge(int u,int v,int a):u(u),v(v),a(a){}
        friend bool operator <(const edge&A,const edge&B) {
            return A.a>B.a;
        }
    }e[N];
    
    int ec,fir[N],nxt[N],to[N],val[N];
    void add(int u,int v,int w) {
        nxt[++ec]=fir[u]; fir[u]=ec; to[ec]=v; val[ec]=w;
        nxt[++ec]=fir[v]; fir[v]=ec; to[ec]=u; val[ec]=w;
    }
    
    int fa[N];
    int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } 
    
    int f[N][20],vv[N];
    
    int ec2,fi[N],nx[N],tt[N];
    void ADD(int u,int v) {
        nx[++ec2]=fi[u]; fi[u]=ec2; tt[ec2]=v;
    }
    
    LL fans[N],dis[N];
    void dfs(int x,int F) {
        f[x][0]=F;
        fans[x]=inf;
        if(x<=n) fans[x]=dis[x];
        For(i,1,19) f[x][i]=f[f[x][i-1]][i-1];
        for(int i=fi[x];i;i=nx[i]) {
            dfs(tt[i],x);
            fans[x]=min(fans[x],fans[tt[i]]);
        }
    }
    
    int totnode;
    void kruskal(int n) {
        sort(e+1,e+m+1);
        totnode=n;
        For(i,1,n*2) fa[i]=i;
        For(i,1,m) {
            int x=e[i].u,y=e[i].v;
            int fx=find(x),fy=find(y);
            if(fx!=fy) {
                totnode++;
                vv[totnode]=e[i].a;
                ADD(totnode,fx); ADD(totnode,fy);
                fa[fx]=fa[fy]=totnode;
            }
        }
        dfs(totnode,0);
    }
    
    struct node {
        int u; LL d; 
        node(int u,LL d):u(u),d(d){}
        friend bool operator <(const node&A,const node&B) {
            return A.d>B.d;
        }
    };
    
    priority_queue<node>que;
    int vis[N];
    void dijkstra(int s) {
        For(i,1,n) dis[i]=inf,vis[i]=0; 
        dis[s]=0; 
        que.push(node(s,0));
        while(!que.empty()) {
            node tp=que.top();
            que.pop();
            if(vis[tp.u]||dis[tp.u]!=tp.d) continue; 
            vis[tp.u]=1;
            for(int i=fir[tp.u];i;i=nxt[i]) {
                int y=to[i];
                if(dis[y]>dis[tp.u]+val[i]) {
                    dis[y]=dis[tp.u]+val[i];
                    que.push(node(y,dis[y])); 
                }
            } 
        } 
    }
    
    void init() {
        ec=ec2=0;
        memset(fir,0,sizeof(fir));
        memset(fi,0,sizeof(fi));
    }
    
    int main() {
    #ifdef ANS
        freopen(".in","r",stdin);
        freopen(".out","w",stdout);
    #endif
        read(T);
        while(T--) {
            init();
            read(n); read(m);
            For(i,1,m) {
                int u,v,l,a;
                read(u); read(v); read(l); read(a);
                add(u,v,l);
                e[i]=edge(u,v,a);
            } 
            dijkstra(1);
            kruskal(n);
            read(Q); read(K); read(S);
            LL ans=0;
            while(Q--) {
                int v0,p0;
                read(v0); read(p0);
                int x=(v0+ans%n*K%n-1)%n+1;
                int p=(p0+ans%(S+1)*K%(S+1))%(S+1);
                Rep(i,19,0) if(f[x][i]&&vv[f[x][i]]>p) 
                    x=f[x][i];
                ans=fans[x];
                printf("%lld
    ",ans);
            }
        } 
        Formylove;
    }
    View Code
  • 相关阅读:
    ArrayBlockingQueue的使用案例:
    mysql中insert into select from的使用
    springboot项目中进行并发测试
    springboot自己实现mysql主从数据切换机制
    启动zuul时候报错:The bean 'proxyRequestHelper', defined in class path resource [org/springframework/cloud/netflix/zuul
    redis集群
    postman创建mocker Server
    springcloud应用思考
    vue进行路由拼图的使用案例
    【适合N卡独显电脑的环境配置】Tensorflow教程-Windows 10下安装tensorflow 1.5.0 GPU with Anaconda
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9550415.html
Copyright © 2020-2023  润新知