Different issues of "optimal" have different meanings, some "minimal", some "the greatest." This blog "minimal" is the "best."
When the minimum spanning tree with kruthkal, assuming now take (u, v) was added spanning tree;
Create a node cnt, cnt that the weight is dis [u] [v], and the connection (cnt, u), (cnt, v);
Finally, the new point and somewhat original form of a tree structure, which is kruthkal reconstruction tree.
We can see from the contribution process, all existing nodes are leaf nodes.
Limited by the order of addition, for a new point, after a certain point is greater than the added weight to the point of addition.
From the perspective of the reconstruction of the tree, for the new point, the weight of their ancestors certainly larger than this point.
So we said, the reconstruction of the tree is to satisfy the heap property
Difficult to think, LCA is the longest side of the two nodes between two points on a minimum spanning tree.
So, kruthkal reconstruct the tree can solve the problem?
It can be transformed into the problem of communication block tree.
for example:
Given an undirected graph, edge with a right side. Asked s, k, it represents a departure from s, without the right side than k edges, reach a maximum number of points.
Artwork can be reconstructed from the trees in the reconstruction s, doubling find the right value does not exceed the minimum depth k ancestors fa.
So fa leaf node to the root of the subtree can go through the weight does not exceed k sides to reach each other.
Reconstruction process is actually characterized by the edge weight value, the eigenvalues satisfy a node is added to the sub-tree, the problem of communication block transferred to the tree.
In doing so inquiries about eigenvalues, only to find the appropriate root on it.
In fact, seek starting from v after only a side elevation of less than p to the point, the shortest distance to 1.
First come the shortest wave, and then press the reconstructed sea level, where the maximum spanning tree structure, so that the root was the lowest altitude.
Then multiplying position seeking ancestors.
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<queue> 6 #include<algorithm> 7 #define mkpr make_pair 8 #define LL long long 9 using namespace std; 10 const int N=200005,M=400005; 11 inline LL read(){ 12 LL x=0;char ch=getchar(); 13 while(ch<'0'||ch>'9')ch=getchar(); 14 while(ch>='0'&&ch<='9'){ 15 x=x*10+ch-'0'; 16 ch=getchar(); 17 } 18 return x; 19 } 20 21 LL T,n,m,cnt,q,k,s; 22 23 struct _mp{ 24 int x,y,h; 25 L LL; 26 is } MP [M << . 1 ]; // picture 27 28 struct Node { 29 int Y, NXT; LL L; 30 } E [M << . 1 ]; // copy shortest run 31 int of He [M << . 1 ], TOT = 0 ; 32 inline void AD ( int X, int Y, L LL) { 33 is ++ TOT; 34 is E [TOT] .y = Y; E [TOT] .L = L; E [TOT] .nxt of He = [X]; of He [X] = TOT; 35 } 36 37 [ inline void init(){ 38 n=read();m=read();cnt=n; 39 for(int i=1;i<=m;++i){ 40 mp[i].x=read();mp[i].y=read();mp[i].l=(LL)read();mp[i].h=read(); 41 ad(mp[i].x,mp[i].y,mp[i].l);ad(mp[i].y,mp[i].x,mp[i].l); 42 } 43 } 44 45 LL d[M<<1]; 46 int v[N]; 47 priority_queue<pair<LL,int> > que; 48 inline void dij(){ 49 memset(v,0,sizeof(v)); 50 d[1]=0;que.push(mkpr(0,1)); 51 while(!que.empty()){ 52 int x=que.top().second;que.pop(); 53 if(v[x])continue; 54 v[x]=1; 55 for(int i=he[x];i;i=e[i].nxt){ 56 int y=e[i].y; 57 if(d[y]>d[x]+e[i].l) 58 d[y]=d[x]+e[i].l,que.push(mkpr(-d[y],y)); 59 } 60 } 61 } 62 63 LL mn[M<<1]; 64 int fa[M<<1][25]; 65 inline void dfs(int now){ 66 mn[now]=d[now]; 67 for(int i=he[now];i;i=e[i].nxt){ 68 int y=e[i].y; 69 fa[y][0]=now; 70 DFS (Y); 71 is Mn [now] = min (Mn [now], Mn [Y]); 72 } 73 is } // statistics for each sub shortest distance to the point in the tree 1 74 75 int F [M << . 1 ], Val [M]; 76 inline BOOL CMP (_mp A, B _mp) { 77 return AH> BH; 78 } 79 inline int FND ( int X) { 80 return ? F [X] X X == :( F [X] = FND (F [X])); 81 } 82 inline void Kruth () { 83 Memset (of He,0,sizeof(he));tot=0; 84 sort(mp+1,mp+m+1,cmp); 85 for(int i=1;i<=n;++i)f[i]=i; 86 for(int i=1;i<=m;++i){ 87 int fx=fnd(mp[i].x),fy=fnd(mp[i].y); 88 if(fx==fy)continue; 89 ++cnt; 90 f[fx]=f[fy]=f[cnt]=cnt; 91 val[cnt]=mp[i].h;//新建节点 92 ad(cnt,fx,0);ad(cnt,fy,0); 93 } 94 dfs(cnt); 95 } 96 97 inline void clr(){ 98 memset(mn,0x3f,sizeof(mn)); 99 memset(he,0,sizeof(he));tot=0; 100 memset(f,0,sizeof(f)); 101 memset(d,0x3f,sizeof(d)); 102 } 103 104 int main(){ 105 T=read(); 106 while(T--){ 107 clr(); 108 init(); 109 dij(); 110 kruth(); 111 for(int j=1;(1<<j)<=cnt;++j){ 112 for(int i=1;i<=cnt;++i){ 113 fa[i][j]=fa[fa[i][j-1]][j-1]; 114 } 115 } 116 q=read();k=read();s=read(); 117 LL ans=0; 118 LL h0,s0; 119 while(q--){ 120 s0=read();h0=read(); 121 h0=(h0+k*ans)%(s+1); 122 s0=(s0+k*ans-1)%n+1; 123 for(int j=22;j>=0;--j){ 124 if(fa[s0][j]&&val[fa[s0][j]]>h0)s0=fa[s0][j]; 125 } 126 the printf ( " % LLD \ n- " , Mn [S0]); 127 ANS = Mn [S0]; 128 } 129 } 130. return 0 ; 131 is } 132 / * This code is LL int mix, very open space rigorous. 133 people looked very uncomfortable. 134 but I do not want changed.
135 * /
I also thought about the tree to the cross