用EK算法来做最大流问题,相较于FF算法,EK算法先用bfs找出最小流,然后从汇点开始扣减容量到汇点


const int N = 2e3 + 86;
struct edge
{
    int to, nxt, w;
} e[N * 2];
int hd[N], tot = 1;
void add(int u, int v, int w)
{
    e[++tot] = (edge){v, hd[u], w};
    hd[u] = tot;
}
int n, m, x, flow[N], last[N];
bitset<286> vis;

int bfs()
{
    memset(last, 0, sizeof(last));
    queue<int> q;
    q.push(1);
    flow[1] = 9e8 + 86;
    while (!q.empty())
    {
        int p = q.front();
        q.pop();
        if (p == n)
            break;
        for (int eg = hd[p]; eg; eg = e[eg].nxt)
        {
            int to = e[eg].to, vol = e[eg].w;
            if (vol > 0 && !last[to])
            {
                last[to] = eg;
                flow[to] = min(flow[p], vol);
                q.push(to);
            }
        }
    }
    return last[n];
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    //IN;OUT;
    cin >> n >> m >> x;
    f(i, 1, m)
    {
        int x, y, val;
        cin >> x >> y >> val;
        add(x, y, val);
        add(y, x, 0);
    }
    LL ans = 0;
    while (bfs())
    {
        ans += flow[n];
        for (int i = n; i != 1; i = e[last[i] ^ 1].to) // 从汇点原路返回更新残余容量
        {
            e[last[i]].w -= flow[n];
            e[last[i] ^ 1].w += flow[n];
        }
    }
    if (ans)
    {
        cout << ans << " ";
        cout << (x / ans + (x % ans ? 1 : 0));
    }
    else
        cout << "Orz Ni Jinan Saint Cow!";
    return 0;
}
此文章已被阅读次数:正在加载...更新于