NOI2018 归程

题解给了个假的dijkstra?

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<bitset>
#define N 200100
#define M 400100
#define Inf 2147483647
using namespace std;

typedef pair<int,int> pii;

int tt,n,m,q,k,s;

struct Graph
{
    struct Edge
    {
        int to,nxt,l,a;
        Edge(){}
        Edge(const int &to,const int &nxt,const int &l,const int &a):to(to), nxt(nxt), l(l), a(a) {}
    }e[(N+M)<<1];

    struct MST
    {
        int x,y,w;
        MST(){}
        MST(const int &x,const int &y,const int &w):x(x),y(y),w(w){}
    }r[(N+M)<<1];
    
    struct cmp
    {
        inline bool operator()(const MST &m1,const MST &m2)const {
            return m1.w>m2.w;
        }
    };
    
    int tot,hd[N+M],d[N+M],v[N+M],fa[N+M],mcost[N+M],anc[N+M][21];
    bitset<N+M> vis;

    inline void init(){
        tot=1;
        memset(hd,0,sizeof(hd));
        vis.reset();
    }

    inline void add(const int &i,const int &u,const int &v,const int &l,const int &a){
        e[++tot]={v,hd[u],l,a},hd[u]=tot;
        e[++tot]={u,hd[v],l,a},hd[v]=tot;
        r[i]=MST(u,v,a);
    }

    inline void dijkstra(int s=1){
        for(int i=1;i<=n;++i)d[i]=Inf;
        priority_queue<pii,vector<pii>,greater<pii>>q;
        d[s]=0,q.push({0,s});
        while(!q.empty()){
            auto [aa,bb]=q.top();
            q.pop();
            if(vis[bb])continue;
            vis[bb]=1;
            //printf("%d\t:::\n",bb);
            for(int eg=hd[bb];eg;eg=e[eg].nxt){
                if(d[e[eg].to]>aa+e[eg].l){
                    //printf("%d:::::%d<--%d+%d\n",e[eg].to,d[e[eg].to],aa,e[eg].l);
                    d[e[eg].to]=aa+e[eg].l;
                    q.push({d[e[eg].to],e[eg].to});
                }
            }
        }
        //for (int i = 1; i <= n; ++i) printf("%d%c", d[i], i == n ? '\n' : ' ');
    }

    inline void LCA_init(int n,int m){
        for(int j=1;j<=20;++j){
            for(int i=1;i<=n+m;++i){
                anc[i][j]=anc[anc[i][j-1]][j-1];
            }
        }
    }
    
    inline int query(int x,int p){
        for(int i=20;i>=0;--i){
            if(anc[x][i]&&v[anc[x][i]]>p)x=anc[x][i];
        }
        return mcost[x];
    }

    inline int fnd(int x){return x==fa[x]?x:fa[x]=fnd(fa[x]);}

    inline void kruskal(int n,int m){
        for(int i=1;i<=n+m;++i)fa[i]=i;
        for(int i=1;i<=n;++i)mcost[i]=d[i],v[i]=-1;
        sort(r+1,r+m+1,cmp());
        for(int i=1;i<=m;++i){
            int x=fnd(r[i].x),y=fnd(r[i].y);
            if(x==y)continue;
            v[n+i]=r[i].w;
            fa[fnd(x)]=fa[fnd(y)]=n+i;
            mcost[n+i]=min(mcost[x],mcost[y]);
            anc[x][0]=anc[y][0]=n+i;
        }
    }
} ss;

int main(){
    scanf("%d",&tt);
    while(tt--){
        int lastans=0;
        ss.init();
        scanf("%d%d",&n,&m);
        for(int i=1,u,v,l,a;i<=m;++i){
            scanf("%d%d%d%d",&u,&v,&l,&a);
            ss.add(i,u,v,l,a);
        }
        ss.dijkstra();ss.kruskal(n,m);ss.LCA_init(n,m);
        scanf("%d%d%d",&q,&k,&s);
        for(int i=1,v0,p0;i<=q;++i){
            scanf("%d%d",&v0,&p0);
            int vv=(v0+1ll*lastans*k-1)%n+1,pp=(p0+1ll*lastans*k)%(s+1);
          //  printf("---%d-%d__(v,p)____",vv,pp);
            printf("%d\n",lastans=ss.query(vv,pp));
        }
    }
}
上一篇
下一篇