【BZOJ5415&UOJ393】归程(Kruskal重构树,最短路)

题意:From https://www.cnblogs.com/Memory-of-winter/p/11628351.html

 

 思路:先从1开始跑一遍dijkstra,建出kruskal重构树之后每个叶子结点的权值为它到1的距离

询问等价于从v开始只要倍增的点的权值>p就往上跳,这样跳到某个点u之后询问u的子树中叶子结点最小的权值

因为是静态的,实际上可以不把kruskal实际建出来,只要维护倍增数组和子树中最小值即可

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef long double ld;
  7 typedef pair<int,int> PII;
  8 typedef pair<ll,int> Pli;
  9 typedef pair<ll,ll> Pll;
 10 typedef vector<int> VI;
 11 typedef vector<PII> VII;
 12 typedef pair<ll,ll>P;
 13 #define N  400000+10
 14 #define M  800000+10
 15 #define INF 4e9+10
 16 #define fi first
 17 #define se second
 18 #define MP make_pair
 19 #define pb push_back
 20 #define pi acos(-1)
 21 #define mem(a,b) memset(a,b,sizeof(a))
 22 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 23 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 24 #define lowbit(x) x&(-x)
 25 #define Rand (rand()*(1<<16)+rand())
 26 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 27 #define ls p<<1
 28 #define rs p<<1|1
 29 #define fors(i) for(auto i:e[x]) if(i!=p)
 30 
 31 const int MOD=1e9+7,inv2=(MOD+1)/2;
 32       //int p=1e6+3;
 33       //double eps=1e-6;
 34       int dx[4]={-1,1,0,0};
 35       int dy[4]={0,0,-1,1};
 36 
 37 struct edge
 38 {
 39     int x,y,l,a;
 40 }a[M];
 41 
 42 bool cmp(edge a,edge b)
 43 {
 44     return a.a>b.a;
 45 }
 46 
 47 ll dis[N],val[N];
 48 int f[N][21],head[N],vet[M],nxt[M],len[M],vis[N],fa[N],n,m,num,tot;
 49 
 50 int read()
 51 {
 52    int v=0,f=1;
 53    char c=getchar();
 54    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 55    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 56    return v*f;
 57 }
 58 
 59 ll readll()
 60 {
 61    ll v=0,f=1;
 62    char c=getchar();
 63    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 64    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 65    return v*f;
 66 }
 67 
 68 void add(int a,int b,int c)
 69 {
 70     nxt[++tot]=head[a];
 71     vet[tot]=b;
 72     len[tot]=c;
 73     head[a]=tot;
 74 }
 75 
 76 void dijkstra()
 77 {
 78     priority_queue<Pli> q;
 79     rep(i,1,n*2) dis[i]=INF,vis[i]=0;
 80     q.push(MP(0,1)); dis[1]=0;
 81     while(!q.empty())
 82     {
 83         int u=q.top().se;
 84         q.pop();
 85         if(vis[u]) continue;
 86         vis[u]=1;
 87         int e=head[u];
 88         while(e)
 89         {
 90             int v=vet[e];
 91             if(dis[u]+len[e]<dis[v])
 92             {
 93                 dis[v]=dis[u]+len[e];
 94                 q.push(MP(-dis[v],v));
 95             }
 96             e=nxt[e];
 97         }
 98     }
 99 }
100 
101 int dsu(int k)
102 {
103     if(fa[k]!=k) fa[k]=dsu(fa[k]);
104     return fa[k];
105 }
106 
107 void Add(int x,int y)
108 {
109     f[y][0]=x;
110     dis[x]=min(dis[x],dis[y]);
111 }
112 
113 int calc(int u,ll p)
114 {
115     per(i,20,0)
116      if(val[f[u][i]]>p) u=f[u][i];
117     return u;
118 }
119 
120 void build()
121 {
122     num=n;
123     rep(i,1,2*n) fa[i]=i;
124     sort(a+1,a+m+1,cmp);
125     rep(i,1,m)
126     {
127         int p=dsu(a[i].x),q=dsu(a[i].y);
128         if(p!=q)
129         {
130             num++;
131             fa[p]=fa[q]=num;
132             val[num]=a[i].a;
133             Add(num,p);
134             Add(num,q);
135             if(num==2*n-1) break;
136         }
137     }
138     rep(i,1,20)
139      rep(j,1,num) f[j][i]=f[f[j][i-1]][i-1];
140 }
141 
142 void solve()
143 {
144     int q=read(),k=read(),s=read();
145     ll lastans=0;
146     while(q--)
147     {
148         int v=read();
149         ll p=readll();
150         if(k==0)
151         {
152             v=(v-1)%n+1;
153             p=p%(s+1);
154         }
155          else
156          {
157              v=(v+lastans-1)%n+1;
158              p=(p+lastans)%(s+1);
159          }
160         int t=calc(v,p);
161         lastans=dis[t];
162         printf("%lld\n",lastans);
163     }
164 }
165 int main()
166 {
167     int cas=read();
168     while(cas--)
169     {
170         n=read(),m=read();
171         tot=0;
172         rep(i,1,n) head[i]=0;
173         rep(i,1,m)
174         {
175             a[i].x=read(),a[i].y=read(),a[i].l=read(),a[i].a=read();
176             add(a[i].x,a[i].y,a[i].l);
177             add(a[i].y,a[i].x,a[i].l);
178         }
179         dijkstra();
180         build();
181         solve();
182     }
183     return 0;
184 }

posted on 2019-12-11 20:00  myx12345  阅读(151)  评论(0编辑  收藏  举报

导航