Aizu 2304 Reverse Roads

原题链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2304

题意:

给你一个网络,其中每条边的容量是1,你可以通过调整边的方向来获得更大的流量,现在问你能获得的最大流量是多少。并且输出更改方向的边的编号。

题解:

就每条边弄成无向的,并且标记一下是否是原始边,然后跑一发Dinic即可。然后在残余网络上寻找解即可。

代码:

#include<iostream>
#include<stack>
#include<vector>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<queue>
#define MAX_S (1<<10)+10
#define MAX_V 500
#define MAX_N MAX_V
#define INF 1000009
using namespace std;

struct edge {
    int to, cap, rev;
    bool isRev;
    bool isOri;
    int id;

    edge(int t, int c, int r, bool ir, bool io,int iid)
            : to(t), cap(c), rev(r), isRev(ir), isOri(io),id(iid) { }

    edge() { }
};

template <class T>
inline bool scan_d(T &ret)
{
    char c;
    int sgn;
    if(c=getchar(),c==EOF) return 0; //EOF
    while(c!=' -' &&(c<'0' ||c>'9' )) c=getchar();
    sgn=(c==' -' )?-1:1;
    ret=(c==' -' )?0:(c-'0' );
    while(c=getchar(),c>='0' &&c<='9' ) ret=ret*10+(c-'0' );
    ret*=sgn;
    return 1;
}

vector<edge> G[MAX_N];
int level[MAX_V];
int iter[MAX_V];

void init(int totNode) {
    for (int i = 0; i <= totNode; i++)
        G[i].clear();
    memset(level, 0, sizeof(level));
    memset(iter, 0, sizeof(iter));
}

void add_edge(int from,int to,int cap,bool io,int id) {
    G[from].push_back(edge (to, cap, G[to].size(),0,io,id));
    G[to].push_back(edge (from, 0, G[from].size() - 1,1,io,id));
}

void bfs(int s) {
    queue<int> que;
    memset(level, -1, sizeof(level));
    level[s] = 0;
    que.push(s);
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int i = 0; i < G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && level[e.to] < 0) {
                level[e.to] = level[v] + 1;
                que.push(e.to);
            }
        }
    }
}

int dfs(int v,int t,int f) {
    if (v == t)return f;
    for (int &i = iter[v]; i < G[v].size(); i++) {
        edge &e = G[v][i];
        if (e.cap > 0 && level[v] < level[e.to]) {
            int d = dfs(e.to, t, min(f, e.cap));
            if (d > 0) {
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

int max_flow(int s,int t) {
    int flow = 0;
    for (; ;) {
        bfs(s);
        if (level[t] < 0)return flow;
        memset(iter, 0, sizeof(iter));
        int f;
        while ((f = dfs(s, t, INF)) > 0) {
            flow += f;
        }
    }
}

int S,T;

int N,M;

vector<int> ans;

int main() {
    scanf("%d%d", &N, &M);
    for (int i = 0; i < M; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        add_edge(u, v, 1, 1, i + 1);
        add_edge(v, u, 1, 0, i + 1);
    }
    scanf("%d%d", &S, &T);
    int f = max_flow(S, T);
    printf("%d
", f);
    for (int i = 1; i <= N; i++)
        for (int j = 0; j < G[i].size(); j++)
            if (G[i][j].isRev == 0 && G[i][j].isOri == 0 && G[i][j].cap == 0)
                ans.push_back(G[i][j].id);
    printf("%d
", ans.size());
    for (int i = 0; i < ans.size(); i++)
        printf("%d
", ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/HarryGuo2012/p/4851642.html