zoukankan      html  css  js  c++  java
  • NOI2018:归程

    题目大意:题面
    (;;;;;;)给定无向图,每条边有长度和高度,多次询问从某个点pi出发到1号点的最短路,并给出参数qi,规定所有能从pi出发仅通过高度>qi的边到达的点视为可以不耗费代价地到达。

    具体思路:(;;)Kruskal重构树(据说这个算法大家都熟悉,但我怎么好像不知道啊,溜了溜了)
    (;;;;;;)发现可以把边按高度从大到小加入图中(像Kruskal求最小生成树那样),然后图就会变成一堆连通块,然后当一条边联通了两个连通块时,就在重构树上新建一个节点,把两个连通块当成新点的儿子
    (;;;;;;)维护好重构树的每个子树上离1最近点的最近距离,求答案时只要从s向上倍增至联通的边刚刚能露出水面时,当前子树的答案就是这个询问的答案
    (;;;;;;)复杂度为(O(nlogn))

    据说SPFA被卡了,真是大快人心,dij多好啊
    AC代码

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    int n,m,T,q,x,y,z,zz,k,s,v0,p0,lastans,v,p,nowans;
    const int N=1000000,INF=1e9;
    int dis[N],vis[N],f[N],fa[N],ans[N],out[N],FA[N][20],H[N];
    vector<int> son[N];
    struct link
    {
        int top,fi[N],ne[N],la[N],to[N],l[N],h[N];
        inline void clear()
        {
            top=0,memset(fi,0,sizeof fi),memset(ne,0,sizeof ne),memset(la,0,sizeof la),memset(to,0,sizeof to),memset(l,0,sizeof l),memset(h,0,sizeof h);
        }
        inline void add(int x,int y,int z,int H)
        {
            top++,to[top]=y,l[top]=z,h[top]=H;
            if(fi[x]==0)fi[x]=top;else ne[la[x]]=top;
            la[x]=top;
        }
    }L;
    struct node
    {
        int id,dis;
        bool operator < (const node &a) const {return a.dis < dis;}
    };
    priority_queue<node> que;
    inline void DIJKSTRA()
    {
        for(int i=1;i<=n;i++)dis[i]=INF,vis[i]=0;
        dis[1]=0;while(!que.empty())que.pop();
        node tmp;
        tmp.id=1;tmp.dis=0;que.push(tmp);
        while (!que.empty()) 
        {
            int now=que.top().id;
            que.pop();
            if (vis[now]) continue;
            vis[now]=true;
            for (int i=L.fi[now];i;i=L.ne[i]) 
            {
                if (!vis[L.to[i]]&&dis[L.to[i]]>dis[now]+L.l[i]) 
                {
                    dis[L.to[i]]=dis[now]+L.l[i];
                    tmp.id=L.to[i];tmp.dis=dis[L.to[i]];
                    que.push(tmp);
                }
            }
        }
    }
    struct E{int x,y,l,h;}e[N];
    inline bool cmp(E a,E b){return a.h>b.h;}
    inline int ASK(int x){if(fa[x]==x)return x;else return fa[x]=ASK(fa[x]);}
    void dfs(int x)
    {
        for(int i=1;i<=19;i++)FA[x][i]=FA[FA[x][i-1]][i-1];
        for(int i=0;i<son[x].size();i++)
        {
            dfs(son[x][i]);
        }
    }
    main()
    {
        scanf("%d",&T);
        while(T--)
        {
            L.clear();lastans=0;scanf("%d%d",&n,&m);memset(FA,0,sizeof FA),memset(fa,0,sizeof fa);
            for(int i=1;i<=2*n;i++)fa[i]=i;
            for(int i=1;i<=m;i++)
            {
    //			x=Read(),y=Read(),z=Read(),zz=Read();
                scanf("%d%d%d%d",&x,&y,&z,&zz);
                e[i].x=x,e[i].y=y,e[i].l=z,e[i].h=zz;
                L.add(x,y,z,zz),L.add(y,x,z,zz);
            }
            DIJKSTRA();sort(e+1,e+1+m,cmp);int tot=n;
            for(int i=1;i<=n;i++)ans[i]=dis[i],H[i]=1e9;
            scanf("%d%d%d",&q,&k,&s);//q=Read(),k=Read(),s=Read();
            for(int i=1;i<=m;i++)
            {
                int fx=ASK(e[i].x),fy=ASK(e[i].y);
                if(fx!=fy)
                {
                    tot++;fa[tot]=tot;FA[tot][0]=tot;fa[fx]=fa[fy]=tot;ans[tot]=min(ans[fx],ans[fy]);FA[fx][0]=FA[fy][0]=tot;
                    H[tot]=e[i].h;
                }
            }
            int root;
            for(int i=1;i<=tot;i++)son[i].clear();
            for(int i=1;i<=tot;i++)
            {
                if(FA[i][0]==i)root=i;else
                son[FA[i][0]].push_back(i);
                
            }
            dfs(root);
            while(q--)
            {
                scanf("%d%d",&v0,&p0);
                v=(v0+k*lastans-1)%n+1;
                p=(p0+k*lastans)%(s+1);
                int now=v;
                for(int i=19;i>=0;i--)if(H[FA[now][i]]>p)now=FA[now][i];
                lastans=ans[now];
                printf("%d
    ",lastans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    CPU飙高,OOM排查?
    反射
    Mybatits
    spring 基础问题
    java中格式化数字0和#区别
    java中File对象的mkdir和mkdirs的区别
    java截取字符串几种方式
    java工厂模式
    Java获取文件路径的几种方式
    jxl生成excel时,增加批注和冻结窗口
  • 原文地址:https://www.cnblogs.com/Orange-User/p/9362738.html
Copyright © 2011-2022 走看看