Cod sursa(job #1167926)

Utilizator manciu_ionIon Manciu manciu_ion Data 6 aprilie 2014 12:12:01
Problema Flux maxim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 9.21 kb
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

#define NMAX 1024
#define pb push_back
#define sz size()
#define mp make_pair
#define INF 0x3f3f3f3f

int C[NMAX][NMAX];
int F[NMAX][NMAX];
int TT[NMAX];
vector<int> G[NMAX];
int N, M;
int q[NMAX];
int viz[NMAX];

int BF()
{
    int incq, sfq, nod, j, V;

    memset(viz, 0, sizeof(viz));
    viz[1] = 1;
    incq = sfq = 0;
    q[sfq++] = 1;
    for ( ; incq < sfq and !viz[N]; )
    {
        nod = q[incq++];
        for (j = 0; j < G[nod].size(); j++)
            {
                V = G[nod][j];
                if (!viz[V]) {
                    if (F[nod][V]<C[nod][V])
                    {
                        viz[V] = nod;
                        q[sfq++] = V;
                    }
                    else
                    if (F[V][nod]>0)
                    {
                        viz[V] = -nod;
                        q[sfq++] = V;

                    }
                }
            }
    }

    return ( !viz[N] );
}

inline int abs(int x)
{
    if (x<0) return(-x);
    return (x);
}

void ek()
{
    int i, a, b, lg, v;
    int L[NMAX];
    do {
        if (BF()) return;
        L[0] = N; lg = 0;
        a = b = INF;
        while (L[lg] != 1 )
        {
            ++lg;
            L[lg]=abs(viz[L[lg-1]]);
            if (viz[L[lg-1]]>0)
               a=min(a,C[L[lg]][L[lg-1]]-F[L[lg]][L[lg-1]]);
            else
            if (viz[L[lg-1]]<0)
               b=min(a,F[L[lg-1]][L[lg]]);
        }
        v = min(a,b);
        for (i = lg; i > 0; --i)
           if (viz[L[i-1]] > 0)
               F[L[i]][L[i-1]] += v;
           else
               F[L[i-1]][L[i]] -= v;

    } while (1);

}

int main()
{
    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);

    int i, flow = 0, x, y, z, nod;

    scanf("%d %d ", &N, &M);

    for (i = 1; i <= M; i++)
    {
        scanf("%d %d %d ", &x, &y, &z);
        C[x][y] += z;
        G[x].pb(y);
        G[y].pb(x);
    }

    ek();

    for (i = 1; i <= N; ++i)
        flow += F[i][N];

    printf("%d\n", flow);

    fclose(stdin);
    fclose(stdout);
    return 0;
}

/*
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

class Graph {
  public:
    static const int NIL = -1;
    static const int oo = 0x3f3f3f3f;

    class Edge {
      public:
        int from, to, capacity, flow;

        Edge(const int _from = NIL, const int _to = NIL, const int _capacity = 0):
          from(_from),
          to(_to),
          capacity(_capacity),
          flow(0) {}

        bool IsSaturated() const {
            return capacity == flow;
        }
    };

    Graph(const int _V = 0):
      V(_V),
      E(0),
      edges(vector<Edge>()),
      G(vector< vector<int> >(_V, vector<int>())) {}

    int Size() const {
        return V;
    }

    void AddEdge(const Edge &e) {
        edges.push_back(e);
        G[e.from].push_back(E++);
    }

    int MaximumFlow(const int source, const int sink) {
        InitializeNetwork();
        int maxFlow = 0;
        vector<int> father;
        while (BFS(source, sink, father)) {
            for (vector<int>::const_iterator e = G[sink].begin(); e != G[sink].end(); ++e) {
                if (edges[NonE(*e)].IsSaturated() || father[edges[*e].to] == NIL)
                    continue;
                father[sink] = NonE(*e);
                int flow = oo;
                for (int x = sink; x != source; x = edges[father[x]].from)
                    flow = min(flow, edges[father[x]].capacity - edges[father[x]].flow);
                for (int x = sink; x != source; x = edges[father[x]].from) {
                    edges[father[x]].flow += flow;
                    edges[NonE(father[x])].flow -= flow;
                }
                maxFlow += flow;
            }
        }
        ClearResidualNetwork();
        return maxFlow;
    }

  private:
    int V, E;
    vector<Edge> edges;
    vector< vector<int> > G;

    int NonE(const int e) const {
        if (e < E)
            return e + E;
        else
            return e - E;
    }

    void InitializeNetwork() {
        for (int e = 0; e < E; ++e) {
            edges[e].flow = 0;
            edges.push_back(Edge(edges[e].to, edges[e].from, 0));
            G[edges[e].to].push_back(NonE(e));
        }
    }

    bool BFS(const int source, const int destination, vector<int> &father) const {
        father = vector<int>(V, NIL);
        father[source] = 2 * E;
        queue<int> q;
        for (q.push(source); !q.empty(); q.pop()) {
            int x = q.front();
            if (x == destination)
                continue;
            for (vector<int>::const_iterator e = G[x].begin(); e != G[x].end(); ++e) {
                if (!edges[*e].IsSaturated() && father[edges[*e].to] == NIL) {
                    father[edges[*e].to] = *e;
                    q.push(edges[*e].to);
                }
            }
        }
        return father[destination] != NIL;
    }

    void ClearResidualNetwork() {
        for (; int(edges.size()) > E; edges.pop_back())
            G[edges.back().from].pop_back();
    }
};

Graph G;
int Answer;

void Solve() {
    Answer = G.MaximumFlow(0, G.Size() - 1);
}

void Read() {
    ifstream cin("maxflow.in");
    int v, e;
    cin >> v >> e;
    G = Graph(v);
    for (; e > 0; --e) {
        int x, y, c;
        cin >> x >> y >> c;
        G.AddEdge(Graph::Edge(x - 1, y - 1, c));
    }
    cin.close();
}

void Print() {
    ofstream cout("maxflow.out");
    cout << Answer << "\n";
    cout.close();
}

int main() {
    Read();
    Solve();
    Print();
    return 0;
}
*/
/*
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

#define NMAX 1024
#define pb push_back
#define mp make_pair
#define INF 0x3f3f3f3f

int C[NMAX][NMAX];
int F[NMAX][NMAX];
int TT[NMAX];
vector<int> G[NMAX];
int N, M;
int cd[NMAX];
int viz[NMAX];

int BF()
{
    int i, j, nod, V;

    cd[0] = 1;
    cd[1] = 1;
    memset(viz, 0, sizeof(viz));
    viz[1] = 1;

    for (i = 1; i <= cd[0]; i++)
    {
        nod = cd[i];
                if (nod == N) continue;
        int d = G[nod].size();
        for (j = 0; j < d; j++)
            {
                V = G[nod][j];
                if (C[nod][V] == F[nod][V] || viz[V]) continue;
                viz[V] = 1;
                cd[ ++cd[0] ] = V;
                TT[V] = nod;
            }
    }

    return viz[N];
}

int main()
{
    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);

    int i, d, flow, fmin, x, y, z, nod;

    scanf("%d %d ", &N, &M);

    for (i = 1; i <= M; i++)
    {
        scanf("%d %d %d ", &x, &y, &z);
        C[x][y] += z;
        G[x].pb(y);
        G[y].pb(x);
    }

    for (flow = 0; BF();)
        for (i = 0, d = G[N].size(); i < d; i++)
        {
            nod = G[N][i];
            if (F[nod][N] == C[nod][N] || !viz[nod]) continue;
            TT[N] = nod;

            fmin = INF;
            for (nod = N; nod != 1; nod = TT[nod])
                fmin = min(fmin, C[ TT[nod] ][nod] - F[ TT[nod] ][nod]);
            if (fmin == 0) continue;

            for (nod = N; nod != 1; nod = TT[nod])
            {
                F[ TT[nod] ][nod] += fmin;
                F[nod][ TT[nod] ] -= fmin;
            }

            flow += fmin;
        }

    printf("%d\n", flow);

    fclose(stdin);
    fclose(stdout);
    return 0;
}
*/
/*
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

#define NMAX 1024
#define pb push_back
#define sz size()
#define mp make_pair
#define INF 0x3f3f3f3f

int C[NMAX][NMAX];
int F[NMAX][NMAX];
int TT[NMAX];
vector<int> G[NMAX];
int N, M;
int cd[NMAX];
int viz[NMAX];

int BF()
{
    int i, j, nod, V;

    cd[0] = 1;
    cd[1] = 1;
    memset(viz, 0, sizeof(viz));
    viz[1] = 1;

    for (i = 1; i <= cd[0]; i++)
    {
        nod = cd[i];
        for (j = 0; j < G[nod].sz; j++)
            {
                V = G[nod][j];
                if (C[nod][V] == F[nod][V] || viz[V]) continue;
                viz[V] = 1;
                cd[ ++cd[0] ] = V;
                TT[V] = nod;
                if (V == N) return 1;
            }
    }

    return 0;
}

int main()
{
    freopen("maxflow.in", "rt", stdin);
    freopen("maxflow.out", "wt", stdout);

    int i, flow, fmin, x, y, z, nod;

    scanf("%d %d ", &N, &M);

    for (i = 1; i <= M; i++)
    {
        scanf("%d %d %d ", &x, &y, &z);
        C[x][y] += z;
        G[x].pb(y);
        G[y].pb(x);
    }

    for (flow = 0; BF(); flow += fmin)
    {
        fmin = INF;
        for (nod = N; nod != 1; nod = TT[nod])
            fmin = min(fmin, C[ TT[nod] ][nod] - F[ TT[nod] ][nod]);
        for (nod = N; nod != 1; nod = TT[nod])
        {
            F[ TT[nod] ][nod] += fmin;
            F[nod][ TT[nod] ] -= fmin;
        }
    }

    printf("%d\n", flow);

    fclose(stdin);
    fclose(stdout);
    return 0;
}
*/