模板库
这是我的模板库。
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]);
}
}
}