Unverified Commit 0cb87573 authored by 雷蒻's avatar 雷蒻 Committed by GitHub
Browse files

Merge pull request #1411 from OI-wiki/hsfzLZH1-patch-1

Update kth-path.md
parents 4d5df567 d25e3b90
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -127,21 +127,21 @@

#### Splay 系函数(不会多做解释)

1.   `Get(x)` 获取 x 是父亲的哪个⼉子。
2.   `Splay(x)` 通过和 Rotate 操作联动实现把 x 旋转到<font color = "red">当前 Splay 的根</font>
3.   `Rotate(x)`x 向上旋转一层的操作。
1.   `Get(x)` 获取 $x$ 是父亲的哪个⼉子。
2.   `Splay(x)` 通过和 Rotate 操作联动实现把 $x$ 旋转到<font color = "red">当前 Splay 的根</font>
3.   `Rotate(x)`$x$ 向上旋转一层的操作。

#### 新操作

1.   `IsRoot(x)` 判断当前节点是否是所在 Splay 的根。
2.   `Access(x)` 把从根到当前节点的所有点放在⼀条实链里,使根到它成为一条实路径,并且在同一棵 Splay 里。
3.   `Update(x)` 在 Access 操作之后,递归地从上到下 Pushdown 更新信息。
4.   `MakeRoot(x)` 使 x 点成为整棵辅助树的根。
5.   `Link(x, y)` 在 x, y 两点间连⼀一条边。
6.   `Cut(x, y)` 把 x, y 两点间边删掉。
7.   `Find(x)` 找到 x 所在的 Splay 的根节点编号。
8.   `Fix(x, v)` 修改 x 的点权为 v
9.   `Split(x, y)` 提取出 x, y 间的路径,方便做区间操作。
3.   `Update(x)``Access` 操作之后,递归地从上到下 `Pushdown` 更新信息。
4.   `MakeRoot(x)` 使 $x$ 点成为整棵辅助树的根。
5.   `Link(x, y)`$x, y$ 两点间连⼀一条边。
6.   `Cut(x, y)`$x, y$ 两点间边删掉。
7.   `Find(x)` 找到 $x$ 所在的 Splay 的根节点编号。
8.   `Fix(x, v)` 修改 $x$ 的点权为 $v$ 
9.   `Split(x, y)` 提取出 $x, y$ 间的路径,方便做区间操作。

### 宏定义

+16 −14
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ using namespace std;
const int maxn = 5010;
const int maxm = 400010;
const int inf = 2e9;
int n, m, s, t, k, u, v, ww, H[maxn], cnt[maxn], ans;
int n, m, s, t, k, u, v, ww, H[maxn], cnt[maxn];
int cur, h[maxn], nxt[maxm], p[maxm], w[maxm];
int cur1, h1[maxn], nxt1[maxm], p1[maxm], w1[maxm];
bool tf[maxn];
@@ -78,14 +78,13 @@ int main() {
    q.pop();
    cnt[x.x]++;
    if (x.x == t && cnt[x.x] == k) {
      printf("%d\n", ans);
      printf("%d\n", x.v);
      return 0;
      ans++;
    }
    if (cnt[x.x] > k) continue;
    for (int j = h[x.x]; j; j = nxt[j]) q.push({p[j], x.v + w[j]});
  }
  printf("%d\n", ans);
  printf("-1\n");
  return 0;
}
```
@@ -159,7 +158,7 @@ int main() {
#include <queue>
using namespace std;
const int maxn = 200010;
int n, m, s, t, k, x, y, ww, cnt, ans, fa[maxn];
int n, m, s, t, k, x, y, ww, cnt, fa[maxn];
struct Edge {
  int cur, h[maxn], nxt[maxn], p[maxn], w[maxn];
  void add_edge(int x, int y, int z) {
@@ -212,7 +211,7 @@ struct LeftistTree {
} st;
void dfs2(int x) {
  vis[x] = true;
  if (fa[x] && fa[x] != n) st.rt[x] = st.merge(st.rt[x], st.rt[fa[x]]);
  if (fa[x]) st.rt[x] = st.merge(st.rt[x], st.rt[fa[x]]);
  for (int j = e2.h[x]; j; j = e2.nxt[j])
    if (fa[e2.p[j]] == x && !vis[e2.p[j]]) dfs2(e2.p[j]);
}
@@ -220,7 +219,7 @@ int main() {
  scanf("%d%d%d%d%d", &n, &m, &s, &t, &k);
  for (int i = 1; i <= m; i++)
    scanf("%d%d%d", &x, &y, &ww), e1.add_edge(x, y, ww), e2.add_edge(y, x, ww);
  Q.push({n, 0});
  Q.push({t, 0});
  while (!Q.empty()) {
    a = Q.top();
    Q.pop();
@@ -230,10 +229,13 @@ int main() {
    for (int j = e2.h[a.x]; j; j = e2.nxt[j]) Q.push({e2.p[j], a.v + e2.w[j]});
  }
  if (k == 1) {
    printf("%d\n", dist[1]);
    if (tf[s])
      printf("%d\n", dist[s]);
    else
      printf("-1\n");
    return 0;
  }
  dfs(n);
  dfs(t);
  for (int i = 1; i <= n; i++)
    if (tf[i])
      for (int j = e1.h[i]; j; j = e1.nxt[j])
@@ -243,8 +245,8 @@ int main() {
                st.rt[i],
                st.newnode({e1.p[j], dist[e1.p[j]] + e1.w[j] - dist[i]}));
  for (int i = 1; i <= n; i++) vis[i] = false;
  dfs2(n);
  if (st.rt[1]) Q.push({st.rt[1], dist[1] + st.v[st.rt[1]].v});
  dfs2(t);
  if (st.rt[s]) Q.push({st.rt[s], dist[s] + st.v[st.rt[s]].v});
  while (!Q.empty()) {
    a = Q.top();
    Q.pop();
@@ -257,10 +259,10 @@ int main() {
      Q.push({st.lc[a.x], a.v - st.v[a.x].v + st.v[st.lc[a.x]].v});
    if (st.rc[a.x])
      Q.push({st.rc[a.x], a.v - st.v[a.x].v + st.v[st.rc[a.x]].v});
    int t = st.rt[st.v[a.x].x];
    if (t) Q.push({t, a.v + st.v[t].v});
    x = st.rt[st.v[a.x].x];
    if (x) Q.push({x, a.v + st.v[x].v});
  }
  printf("%d\n", ans);
  printf("-1\n");
  return 0;
}
```