最大流

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <queue>
#include <map>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <numeric>
#include <cmath>
#include <iomanip>
#include <deque>
#include <bitset>
#include <cassert>
//#include <unordered_set>
//#include <unordered_map>
#define ll              long long
#define pii             pair<int, int>
#define rep(i,a,b)      for(int  i=a;i<=b;i++)
#define dec(i,a,b)      for(int  i=a;i>=b;i--)
#define forn(i, n)      for(int i = 0; i < int(n); i++)
using namespace std;
int dir[4][2] = { { 1,0 },{ 0,1 } ,{ 0,-1 },{ -1,0 } };
const long long INF = 0x7f7f7f7f7f7f7f7f;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int mod = 998244353;

inline int read()
{
    int x = 0; bool f = true; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = false; c = getchar(); }
    while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return f ? x : -x;
}
inline ll gcd(ll m, ll n)
{
    return n == 0 ? m : gcd(n, m % n);
}
void exgcd(ll A, ll B, ll& x, ll& y)
{
    if (B) exgcd(B, A % B, y, x), y -= A / B * x; else x = 1, y = 0;
}
inline ll qpow(ll x, ll n) {
    int r = 1;
    while (n > 0) {
        if (n & 1) r = 1ll * r * x %mod;
        n >>= 1; x = 1ll * x * x %mod;
    }
    return r;
}
inline int inv(int x) {
    return qpow(x, mod - 2);
}
ll lcm(ll a, ll b)
{
    return a * b / gcd(a, b);
}
/**********************************************************/
const int N = 2e3 + 5;

const int maxn = 200 + 5;

struct Edge
{
    int from, to, cap, flow;
    Edge() {}
    Edge(int f, int t, int c, int flow) :from(f), to(t), cap(c), flow(flow) {}
};

struct Dinic
{
    int n, m, s, t;
    vector<Edge> edges;
    vector<int> G[maxn];
    bool vis[maxn];
    int cur[maxn];
    int d[maxn];

    void init(int n, int s, int t)
    {
        this->n = n, this->s = s, this->t = t;
        edges.clear();
        for (int i = 1; i <= n; i++) G[i].clear();
    }

    void AddEdge(int from, int to, int cap)
    {
        edges.push_back(Edge(from, to, cap, 0));
        edges.push_back(Edge(to, from, 0, 0));
        m = edges.size();
        G[from].push_back(m - 2);
        G[to].push_back(m - 1);
    }

    bool BFS()
    {
        memset(vis, 0, sizeof(vis));
        queue<int> Q;
        d[s] = 0;
        Q.push(s);
        vis[s] = true;
        while (!Q.empty())
        {
            int x = Q.front(); Q.pop();
            for (int i = 0; i < G[x].size(); i++)
            {
                Edge& e = edges[G[x][i]];
                if (!vis[e.to] && e.cap > e.flow)
                {
                    vis[e.to] = true;
                    Q.push(e.to);
                    d[e.to] = 1 + d[x];
                }
            }
        }
        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& e = edges[G[x][i]];
            if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0)
            {
                e.flow += f;
                edges[G[x][i] ^ 1].flow -= f;
                flow += f;
                a -= f;
                if (a == 0) break;
            }
        }
        return flow;
    }

    int Maxflow()
    {
        int flow = 0;
        while (BFS())
        {
            memset(cur, 0, sizeof(cur));
            flow += DFS(s, INF);
        }
        return flow;
    }
}DC;

int main()
{
    int n, m;
    while (scanf("%d%d", &m, &n) == 2)
    {
        DC.init(n, 1, n);
        while (m--)
        {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            DC.AddEdge(u, v, w);
        }
        printf("%d\n", DC.Maxflow());
    }
    return 0;
}

 

posted @ 2020-08-12 15:04  DeaL57  阅读(140)  评论(0编辑  收藏  举报