网络流
最大权闭合子图/最大点权独立集/最小点权覆盖
struct DICNIC
{
int st, gl, cnt, sum;
int hed[MAXN], lel[MAXN], cur[MAXN];
struct SF {int to, nxt; ll cap;}edg[MAXM << 1];
void add_edge(int x, int y, ll c)
{
edg[++cnt].to = y; edg[cnt].cap = c; edg[cnt].nxt = hed[x]; hed[x] = cnt;
edg[++cnt].to = x; edg[cnt].cap = 0; edg[cnt].nxt = hed[y]; hed[y] = cnt;
}
void init()
{
st = sum = 0; cnt = -1; gl = m + n + 1;
rep(i, 0, gl) hed[i] = -1;
}
bool bfs()
{
queue <int> Q; rep(i, st, gl) lel[i] = 0;
int u, v; Q.push(st); lel[st] = 1;
while(!Q.empty())
{
int u = Q.front(); Q.pop();
for(int i = hed[u]; ~i; i = edg[i].nxt)
{
v = edg[i].to;
if(!lel[v] && edg[i].cap > 0) {lel[v] = lel[u] + 1; Q.push(v);}
}
}
return (lel[gl]);
}
ll dfs(int u, ll flow)
{
if(u == gl) return flow;
int v; ll nflow = 0, tmp;
for(int &i = cur[u]; ~i; i = edg[i].nxt)
{
v = edg[i].to;
if(lel[v] == lel[u] + 1 && edg[i].cap > 0)
{
tmp = dfs(v, min(flow, edg[i].cap));
flow -= tmp, edg[i].cap -= tmp;
nflow += tmp, edg[i ^ 1].cap += tmp;
if(!flow) break;
}
}
if(!flow) lel[u] = 0;
return nflow;
}
ll dicnic()
{
ll tmp, res = 0;
while(bfs())
{
rep(i, st, gl) cur[i] = hed[i];
while(tmp = dfs(st, INF)) res += tmp;
}
return res;
}
}dic;
MCMF
struct MCMF
{
int st, gl, cnt; ll mflow, mcost;
int pre[MAXN], hed[MAXN], mark[MAXN], cost[MAXN];
struct SF{int u, v, nxt; ll cap, val;}edg[MAXM << 1];
void init()
{
cnt = -1, st = 0, gl = n * 2 + 1;
rep(i, 0, gl) hed[i] = -1;
}
void add_edge(int x, int y, int c, int v)
{
edg[++cnt].u = x, edg[cnt].v = y, edg[cnt].cap = c, edg[cnt].val = v, edg[cnt].nxt = hed[x], hed[x] = cnt;
edg[++cnt].u = y, edg[cnt].v = x, edg[cnt].cap = 0, edg[cnt].val = -v, edg[cnt].nxt = hed[y], hed[y] = cnt;
}
bool spfa()
{
queue <int> Q;
rep(i, 0, gl) mark[i] = 0, pre[i] = -1, cost[i] = INF;
mark[st] = 1; cost[st] = 0; Q.push(st);
while(!Q.empty())
{
int u = Q.front(); mark[u] = 0; Q.pop();
for(int i = hed[u]; ~i; i = edg[i].nxt)
{
int v = edg[i].v;
if(edg[i].cap > 0 && cost[v] > cost[u] + edg[i].val)
{
pre[v] = i; cost[v] = cost[u] + edg[i].val;
if(!mark[v]) mark[v] = 1, Q.push(v);
}
}
}
return (~pre[gl]);
}
ll Mcmf()
{
ll flow = 0;
while(spfa())
{
mflow = INF;
for(int i = pre[gl]; ~i; i = pre[edg[i].u]) mflow = min(mflow, edg[i].cap);
flow += mflow;
for(int i = pre[gl]; ~i; i = pre[edg[i].u])
edg[i].cap -= mflow, edg[i ^ 1].cap += mflow;
mcost += mflow * cost[gl];
}
return mcost;
}
}mcmf;
按时间拆点 分层图
P2754 [CTSC1999]家园/星际转移问题
网格图/对偶图
P4001 [ICPC-Beijing 2006]狼抓兔子