模板库

这是我的模板库。

tarjan 有向图缩点模板

int dfn[N], low[N], cnt, in[N], st[N], tp, scc[N], sc, sum[N];
void tarjan(int u) {
  dfn[u] = low[u] = ++cnt;  st[++tp] = u;  in[u] = 1;
  for (int i = first[u]; i; i = nex[i]) {
    int to = v[i];
    if (!dfn[to])  tarjan(to), chkmin(low[u], low[to]);
    else if (in[to])  chkmin(low[u], dfn[to]);
  }
  if (dfn[u] == low[u]) {
    ++sc;
    do {  scc[st[tp]] = sc;  sum[sc]++;  in[st[tp]] = 0;  tp--;  } while (st[tp + 1] != u);
  }
}

dinic 网络最大流

int dep[N], aim, cur[N];
queue <int> q;
bool bfs(int s,int t) {
  rep (i, 1, tot)  dep[i] = 0;
  dep[s] = 1;  q.push(s);
  while (!q.empty()) {
    auto it = q.front();  q.pop();  cur[it] = first[it];
    for (int i = first[it]; i; i = nex[i]) {
      int to = v[i];
      if (flow[i] && !dep[to])  dep[to] = dep[it] + 1, q.push(to);
    }
  }
  return dep[t] != 0;
}
int dfs(int now,int fl) {
  if (now == aim)  return fl;
  int f = 0;
  for (int i = cur[now]; i; i = nex[i]) {
    cur[now] = i;
    int to = v[i];
    if (dep[to] == dep[now] + 1 && flow[i]) {
      int qwq = dfs(to, min(fl, flow[i]));
      flow[i] -= qwq;  flow[i ^ 1] += qwq;  f += qwq;  fl -= qwq;
      if (!fl)  break;
    }
  }
  return f;
}
int dinic(int s,int t) {
  int ans = 0;  aim = t;
  while (bfs(s, t))  ans += dfs(s, inf);
  return ans;
}

哈希表

class hsmap {
public :
  const static int base = 1 << 23, bs = base - 1;
  int num, nex[N], first[base], v[N];  LL st[N];
  void clear() {
    rep (i, 1, num)  first[st[i] & bs] = 0; num = 0;
  }
  hsmap() {  clear();  }
  int &operator[](LL p) {
    int k = p & bs;
    for (int i = first[k]; i; i = nex[i])  if (st[i] == p)  return v[i];
    nex[++num] = first[k];  first[k] = num;  st[num] = p;
    return v[num] = 0;
  }
} pt;

tarjan 求割点

void tarjan(int x) {
  dfn[x] = low[x] = ++cnt;
  int son = 0;
  for (int i = first[x]; i; i = nex[i]) {
    int to = v[i];
    if (!dfn[to]) {
      tarjan(to);  ++son;  chkmin(low[x], low[to]);
      if (low[to] >= dfn[x] && x != rt)  tot += !vib[x], vib[x] = 1;
    }
    else  chkmin(low[x], dfn[to]);
  }
  if (son >= 2 && x == rt)  tot += !vib[x], vib[x] = 1;
}

tarjan 求割边

void tarjan(int x,int in_edge) {
  dfn[x] = low[x] = ++cnt;
  for (int i = first[x]; i; i = nex[i]) {
    int to = v[i];
    if (!dfn[to]) {
      tarjan(to, i);
      chkmin(low[x], low[to]);
      if (low[to] > dfn[x]) {  vis[i] = vis[i ^ 1] = 1;  }
    }  else {
      if (i != (in_edge ^ 1))  chkmin(low[x], dfn[to]);
    }
  }
}
posted @ 2022-09-06 08:55  Pitiless0514  阅读(87)  评论(1编辑  收藏  举报