ZOJ 2532 求最小割 + Dinic

Dinic模板找到残余网络 + 两个dfs找正流网络和负流网络

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 200;
const int maxe = 5000;
int visit[maxn], rvisit[maxn];
int head[maxn];//head应该为类中的私有成员,但是求最小割的时候要用,为了方便,我们把他提到外面
struct Edge {//Edge也应该为类中的私有成员
        int from, to;
        int next;
        int  cap;
    } edge[maxe];
class Dinic {//我们把Dinic封装为一个类
public:
    Dinic(int _s,int _t){
        s=_s,t=_t;
        cnt=0,res=0;
        memset(head, -1, sizeof(head));
    }
    void addedge(int from, int to, int cap) {
        edge[cnt].from = from, edge[cnt].to = to, edge[cnt].next = head[from];
        edge[cnt].cap = cap, head[from] = cnt++;
        edge[cnt].from = to, edge[cnt].to = from, edge[cnt].next = head[to];
        edge[cnt].cap = 0, head[to] = cnt++;
    }
    int dinic() {
        while (1) {
            memset(dep, -1, sizeof(dep));
            front = 0;
            rear = 0;
            que[rear++] = s;
            dep[s] = 0;
            while (front != rear) {
                i = que[front++];
                for (j = head[i]; j != -1; j = edge[j].next)
                    if (edge[j].cap && dep[edge[j].to] == -1) {
                        dep[edge[j].to] = dep[i] + 1;
                        que[rear++] = edge[j].to;

                    }
            }
            if (dep[t] == -1)
                break;
            memcpy(cur, head, sizeof(head));
            for (i = s, top = 0;;) {
                if (i == t) {
                    min = INF;
                    for (k = 0; k < top; k++)
                        if (min > edge[que[k]].cap) {
                            min = edge[que[k]].cap;
                            front = k;
                        }
                    for (k = 0; k < top; k++) {
                        edge[que[k]].cap -= min;
                        edge[que[k] ^ 1].cap += min;
                    }
                    res += min;
                    i = edge[que[top = front]].from;

                }
                for (j = cur[i]; cur[i] != -1; j = cur[i] = edge[cur[i]].next)
                    if (dep[edge[j].to] == dep[i] + 1 && edge[j].cap)
                        break;
                if (cur[i] != -1) {
                    que[top++] = cur[i];
                    i = edge[cur[i]].to;
                } else {
                    if (top == 0)
                        break;
                    dep[i] = -1;
                    i = edge[que[--top]].from;
                }
            }
        }
        return res;
    }
public:
    int cnt,dep[maxn], que[maxn], cur[maxn];
    int i, j, k, front, rear, top, min, res,s,t;
    
};

void dfs(int u) {
    visit[u] = 1;
    for (int i = head[u]; i != -1; i = edge[i].next) {
        int to = edge[i].to;
        if (visit[to] == 0 && edge[i].cap)
            dfs(to);
    }
}

void rdfs(int u) {
    rvisit[u] = 1;
    for (int i = head[u]; i != -1; i = edge[i].next) {
        int to = edge[i].to;
        if (edge[i ^ 1].cap && rvisit[to] == 0)
            rdfs(to);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("E:\\input.txt", "r", stdin);
#endif // ONLINE_JUDGE
    int n, m, l,i, x, y,c;
    int ans[maxe];
    while (~scanf("%d%d%d", &n, &m, &l)&&n+m+l) {
        Dinic DC(n+m+1,0);
        for (i = 0; i < l; i++) {
            scanf("%d%d%d", &x, &y, &c);
            DC.addedge(x, y, c);
        }
        for (i = 1; i <= n; i++)
            DC.addedge(n + m + 1, i, INF);
        DC.dinic();
        memset(visit, 0, sizeof(visit));
        memset(rvisit, 0, sizeof(rvisit));
        dfs(n + m + 1),rdfs(0);
        int k = 0;
        for (i = 0; i < DC.cnt; i += 2) {
            x = edge[i].from;
            y = edge[i].to;
            if (visit[x] == 1 && rvisit[y] == 1 && edge[i].cap == 0)
                ans[k++] = i / 2 + 1;

        }
        if (k == 0)
            printf("\n");
        else {
            printf("%d", ans[0]);
            for (i = 1; i < k; i++)
                printf(" %d", ans[i]);
            printf("\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/shadandeajian/article/details/81395672