网络流板子之 dinic板子

来源:互联网 发布:皮革护理 知乎 编辑:程序博客网 时间:2024/05/16 08:25
int head[maxn], cnt;int n, m, s, t;bool vis[maxn];int d[maxn], cur[maxn];struct Edge {    int u, v;    int cap, flow;} e[maxn*40]; //因为是双向边  所以记得开二倍vector<int> G[maxn];void init() {    memset(head, -1, sizeof(head));    for (int i = 0; i <= maxn; i++) //一定不要对vector使用mem!!!        G[i].clear();    cnt = 0;}void add(int u, int v, int cap, int f) {    e[cnt].u = u;    e[cnt].v = v;    e[cnt].cap = cap;    e[cnt].flow = f;}void addEdge(int u, int v, int cap) {    add(u, v, cap, 0);    G[u].push_back(cnt++);    add(v, u, 0, 0);    G[v].push_back(cnt++);}bool BFS() {    Fill(vis,0);    queue<int> q;    q.push(s);    vis[s] = 1;    d[s] = 0;    while (!q.empty()) {        int u = q.front(); q.pop();        for (int i = 0; i < G[u].size(); i++) {            Edge &te = e[G[u][i]];            if (!vis[te.v] && te.cap > te.flow) { //只考虑残量网络的弧                vis[te.v] = 1;                d[te.v] = d[u] + 1;                q.push(te.v);            }        }    }    return vis[t];}int dfs(int x, int a) {    if (x == t || a == 0) return a;    int flow = 0, f;    for (int &i = cur[x]; i < G[x].size(); i++) { //从上次考虑的弧        Edge &te = e[G[x][i]];        if (d[x] + 1 == d[te.v] && (f = dfs(te.v, min(a, te.cap - te.flow))) > 0) {            te.flow += f;            e[G[x][i]^1].flow -= f;            flow += f;            a -= f;            if (a == 0) break;        }    }    return flow;}int Dinic() {    int flow = 0;    while (BFS()) {        memset(cur, 0, sizeof(cur));        printf("%d\n",d[t]);        flow += dfs(s, inf);    }    return flow;}
原创粉丝点击