Commit 8609925c authored by 24OI-bot's avatar 24OI-bot
Browse files

style: format markdown files with remark-lint

parent 0b9b8641
Loading
Loading
Loading
Loading
+110 −115
Original line number Diff line number Diff line

## 最小树形图

有向图上的最小生成树(Minimum Directed Spanning Tree)称为最小树形图。
@@ -90,7 +89,6 @@ Tarjan的算法分为**收缩** 与 **伸展**两个过程。接下来先介绍*
### 代码

```cpp

#include <bits/stdc++.h>

using namespace std;
@@ -124,14 +122,14 @@ struct Heap {
Heap *merge(Heap *x, Heap *y) {
  if (!x) return y;
  if (!y) return x;
    if (x->e->w + x->constant > y->e->w + y->constant)
        swap(x, y);
  if (x->e->w + x->constant > y->e->w + y->constant) swap(x, y);
  x->push();
  x->rch = merge(x->rch, y);
    if (!x->lch || x->lch->rk < x->rch->rk)
        swap(x->lch, x->rch);
	if (x->rch) x->rk = x->rch->rk + 1;
	else x->rk = 1;
  if (!x->lch || x->lch->rk < x->rch->rk) swap(x->lch, x->rch);
  if (x->rch)
    x->rk = x->rch->rk + 1;
  else
    x->rk = 1;
  return x;
}
Edge *extract(Heap *&x) {
@@ -152,11 +150,12 @@ void contract() {
  // 将图上的每一个结点与其相连的那些结点进行记录。
  for (int i = 1; i <= n; i++) {
    queue<Heap *> q;
        for (int j = 0; j < in[i].size(); j++) 
			    q.push(new Heap(&in[i][j]));
    for (int j = 0; j < in[i].size(); j++) q.push(new Heap(&in[i][j]));
    while (q.size() > 1) {
            Heap *u = q.front(); q.pop();
            Heap *v = q.front(); q.pop();
      Heap *u = q.front();
      q.pop();
      Heap *v = q.front();
      q.pop();
      q.push(merge(u, v));
    }
    Q[i] = q.front();
@@ -184,9 +183,9 @@ void contract() {
ll expand(int x, int r);
ll expand_iter(int x) {
  ll r = 0;
    for (int u = nxt[x]; u != x; u = nxt[u])
	{
        if (ed[u]->w0 >= INF) return INF;
  for (int u = nxt[x]; u != x; u = nxt[u]) {
    if (ed[u]->w0 >= INF)
      return INF;
    else
      r += expand(ed[u]->v, u) + ed[u]->w0;
  }
@@ -194,40 +193,36 @@ ll expand_iter(int x) {
}
ll expand(int x, int t) {
  ll r = 0;
    for (; x != t; x = fa[x])
	{
  for (; x != t; x = fa[x]) {
    r += expand_iter(x);
    if (r >= INF) return INF;
  }
  return r;
}
void link(int u, int v, int w) {
	in[v].push_back({u, v, w, w}); 
}
void link(int u, int v, int w) { in[v].push_back({u, v, w, w}); }

int main() {
  int rt;
  scanf("%d %d %d", &n, &m, &rt);
    for (int i = 0; i < m; i++) 
	{
  for (int i = 0; i < m; i++) {
    int u, v, w;
    scanf("%d %d %d", &u, &v, &w);
    link(u, v, w);
  }
  // 保证强连通
    for (int i = 1; i <= n; i++) 
        link(i > 1 ? i - 1 : n, i, INF);
  for (int i = 1; i <= n; i++) link(i > 1 ? i - 1 : n, i, INF);
  contract();
  ll ans = expand(rt, n);
    if (ans >= INF) puts("-1");
    else printf("%lld\n", ans);                                                       
  if (ans >= INF)
    puts("-1");
  else
    printf("%lld\n", ans);
  return 0;
}
```


## 参考文献

Uri Zwick. (2013), [Directed Minimum Spanning Trees](http://www.cs.tau.ac.il/~zwick/grad-algo-13/directed-mst.pdf) , Lecture notes on“Analysis of Algorithms”

https://riteme.site/blog/2018-6-18/mdst.html#_3
 <https://riteme.site/blog/2018-6-18/mdst.html#_3>