【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 }
null