链式前向星
namespace Graph_nxt
{
const int maxn = 1e5, maxm = 1e5;
struct Edge
{
int v, f;
friend bool operator <(Edge a, Edge b)
{
return a.f > b.f;
}
};
Edge edg[maxm];
int h[maxn], nxt[maxm];
int esize;
inline void add(int u, int v, int w)
{
esize++;
edg[esize] = { v,w };
nxt[esize] = h[u];
h[u] = esize;
}
}
连通性
并查集
const int maxn = 1000;
struct Unionset
{
int f[maxn];
Unionset(int n)
{
for (int i = 0; i <= n; i++)
{
f[i] = i;
}
}
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
bool query(int x, int y)
{
return find(x) ==find(y);
}
void uni(int x, int y)
{
f[find(x)] = find(y);
}
};
tarjan
namespace Tarjan
{
const int maxn=1000, maxm=1000;
struct Graph
{
Graph()
{
esize = 0;
memset(h,0,sizeof(h));
memset(nxt, 0, sizeof(nxt));
}
int edg[maxm];
int h[maxn], nxt[maxm];
int esize;
inline void add(int u, int v)
{
esize++;
edg[esize] = v;
nxt[esize] = h[u];
h[u] = esize;
}
};
Graph g1, g2;
int dfn[maxn], low[maxn], num = 0, scc[maxn], sccn = 0, sk[maxn], sksize = 0, sum[maxn], mxsum = 0;
void tarjan(int u)
{
dfn[u] = low[u] = ++num;
sk[sksize++] = u;
for (int i = g1.h[u]; i; i = g1.nxt[i])
{
int v = g1.edg[i];
if (!dfn[v])
{
tarjan(v);
low[u] = mn(low[u], low[v]);
}
else if (!scc[v])
{
low[u] = mn(low[u], dfn[v]);
}
}
if (dfn[u] == low[u])
{
sccn++;
while (1)
{
int v = sk[--sksize];
scc[v] = sccn;
if (v == u)break;
}
}
}
}
最短路
dijkstra
namespace Dijkstra
{
const int maxn = 100005, maxm = 200005;
struct Edge
{
int v, w;
bool operator <(const Edge& x)const
{
return w > x.w;
}
};
int e;
struct Graph
{
void ini(int _n)
{
n = _n;
esize = 0;
memset(nxt, 0, sizeof(nxt));
memset(h, 0, sizeof(h));
}
Edge edg[maxm];
int h[maxn], nxt[maxm], esize, n;
inline void add(int u, int v, int w)
{
esize++;
edg[esize] = { v,w };
nxt[esize] = h[u];
h[u] = esize;
}
int dis[maxn], vis[maxn];
void dijkstra(int s)
{
priority_queue<Edge> q;
memset(dis, 127, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[s] = 0;
q.push({ s,0 });
while (!q.empty())
{
int u = q.top().v, w = q.top().w;
q.pop();
if (w != dis[u])continue;
vis[u] = 1;
for (int i = h[u]; i; i = nxt[i])
{
int v = edg[i].v;
if (!vis[v] && dis[v] > w + edg[i].w)
{
dis[v] = w + edg[i].w;
q.push({ v,dis[v] });
}
}
}
}
}g;
}
网络流
dinic
namespace DINIC
{
const int maxn = 205, maxm = 5005 * 2, inf = 0x3f3f3f3f;
struct Edge
{
int v, w;
};
int e;
struct Graph
{
void ini(int _n)
{
n = _n;
esize = 1;
memset(nxt, 0, sizeof(nxt));
memset(h, 0, sizeof(h));
}
Edge edg[maxm];
int h[maxn], nxt[maxm], esize, n;
inline void add(int u, int v, int w)
{
esize++;
edg[esize] = { v,w };
nxt[esize] = h[u];
h[u] = esize;
}
int dep[maxn], inq[maxn], cur[maxn];
int s, t;
long long mxflow;
bool tag;
bool bfs()
{
for (int i = 1; i <= n; i++)
{
cur[i] = h[i];
dep[i] = inf;
inq[i] = 0;
}
queue<int> q;
q.push(s);
dep[s] = 0;
inq[s] = 1;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = h[u]; i; i = nxt[i])
{
int v = edg[i].v;
if (edg[i].w > 0 && dep[u] + 1 < dep[v])
{
dep[v] = dep[u] + 1;
if (!inq[v])
{
q.push(v);
inq[v] = 1;
}
}
}
}
if (dep[t] == inf)return 0;
return 1;
}
inline long long dfs(int u, long long mnflow)
{
long long usflow = 0, tmpflow = 0;
if (u == t)
{
return mnflow;
}
for (int i = cur[u]; i; i = nxt[i])
{
cur[u] = i;
int v = edg[i].v;
if (edg[i].w > 0 && dep[v] == dep[u] + 1)
{
tmpflow = dfs(v, mn(mnflow, edg[i].w));
if (!tmpflow) dep[v] = inf;
edg[i].w -= tmpflow;
edg[i ^ 1].w += tmpflow;
usflow += tmpflow;
mnflow -= tmpflow;
if (!mnflow)break;
}
}
return usflow;
}
long long dinic(int _s, int _e)
{
s = _s;
t = _e;
mxflow = 0;
while (bfs())
{
tag = 1;
while (tag)
{
tag = 0;
mxflow += dfs(s, INT_MAX);
}
}
return mxflow;
}
}g;
}
ISAP
namespace ISAP
{
const int maxn = 1e5, maxm = 1e5;
struct Edge
{
int v, w;
};
struct Graph
{
int h[maxn], nxt[maxm], esize, n;
Edge edg[maxm];
void ini(int _n)
{
n = _n;
memset(h, 0, sizeof(h));
memset(nxt, 0, sizeof(nxt));
esize = 1;
}
void inline add(int u, int v, int w)
{
esize++;
edg[esize] = { v,w };
nxt[esize] = h[u];
h[u] = esize;
}
int cur[maxn], gap[maxn], bfn[maxn], s, t;
void bfs()
{
queue<int> q;
memset(bfn, 0, sizeof(bfn));
memset(gap, 0, sizeof(gap));
for (int i = 1; i <= n; i++)
{
cur[i] = h[i];
}
q.push(t);
bfn[t] = 1;
gap[1]++;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = h[u]; i; i = nxt[i])
{
int v = edg[i].v;
if (bfn[v])continue;
bfn[v] = bfn[u] + 1;
gap[bfn[v]]++;
q.push(v);
}
}
}
long long dfs(int u, int minflow)
{
if (u == t)return minflow;
int useflow = 0;
for (int& i = cur[u]; i; i = nxt[i])
{
int v = edg[i].v;
if (bfn[v] + 1 != bfn[u] || edg[i].w <= 0)continue;
long long tmp = dfs(v, min(minflow, edg[i].w));
if (tmp)
{
useflow += tmp;
minflow -= tmp;
edg[i].w -= tmp;
edg[i ^ 1].w += tmp;
if (!minflow)return useflow;
}
}
gap[bfn[u]]--;
if (!gap[bfn[u]])bfn[s] = n + 1;
bfn[u]++;
gap[bfn[u]]++;
cur[u] = h[u];
return useflow;
}
long long isap(int _s, int _t)
{
s = _s;
t = _t;
bfs();
long long maxflow = 0;
while (bfn[s] <= n)
{
maxflow += dfs(s, INT_MAX);
}
return maxflow;
}
}g;
}
最小费用最大流
namespace MCMF
{
const int maxn = 5005, maxm = 50005 * 2, inf = 0x3f3f3f3f;
struct Edge
{
int v, w, f;
};
struct Graph
{
void ini(int _n)
{
n = _n;
esize = 1;
memset(nxt, 0, sizeof(nxt));
memset(h, 0, sizeof(h));
}
Edge edg[maxm];
int h[maxn], nxt[maxm], esize, n;
inline void add(int u, int v, int w, int f)
{
esize++;
edg[esize] = { v,w,f };
nxt[esize] = h[u];
h[u] = esize;
}
int minf[maxn], pre[maxn], inedg[maxn], flow[maxn];
bool inq[maxn];
int s, t;
int mxflow, mncost;
inline bool spfa()
{
for (int i = 1; i <= n; i++)
{
minf[i] = inf;
inq[i] = 0;
pre[i] = 0;
flow[s] = INT_MAX;
}
queue<int> q;
q.push(s);
minf[s] = 0;
inq[s] = 1;
while (!q.empty())
{
int u = q.front();
q.pop();
inq[u] = 0;
for (int i = h[u]; i; i = nxt[i])
{
int v = edg[i].v;
if (edg[i].w > 0 && minf[u] + edg[i].f < minf[v])
{
minf[v] = minf[u] + edg[i].f;
pre[v] = u;
inedg[v] = i;
flow[v] = mn(flow[u], edg[i].w);
if (!inq[v])
{
q.push(v);
inq[v] = 1;
}
}
}
}
return pre[t];
}
void MCMF(int _s, int _t)
{
s = _s;
t = _t;
mxflow = 0;
mncost = 0;
while (spfa())
{
int x = t;
mxflow += flow[t];
mncost += flow[t] * minf[t];
while (x != s)
{
int i = inedg[x];
edg[i].w -= flow[t];
edg[i ^ 1].w += flow[t];
x = pre[x];
}
}
}
}g;
}