Cod sursa(job #1170051)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 12 aprilie 2014 16:52:47
Problema Critice Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.04 kb
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <vector>
#include <queue>
using namespace std;

ifstream fi ("critice.in");
ofstream fo ("critice.out");

const int dim = 1002;
vector <int> V[dim];
int source, sink, I[dim][dim];

void read (int &N, int &M, int **&C)
{
    fi >> N >> M;

    C = (int **) malloc (sizeof (int *) * (N + 1));
    for (int i = 1; i <= N; i++)
        C[i] = (int *) malloc (sizeof (int) * (N + 1));

    int i, j;
    for (i = 1; i <= N; i++) for (j = 1; j <= N; j++) C[i][j] = 0;

    for (int i = 1, x, y, c; i <= M; i++)
    {
        fi >> x >> y >> c;

        C[x][y] = c;
        C[y][x] = c;

        I[x][y] = I[y][x] = i;

        V[x].push_back (y);
        V[y].push_back (x);
    }
    source = 1;
    sink = N;
}

bool bfs (int N, int *P, int **C, int **F)
{
    int c, v, i;
    queue <int> Q;

    for (i = 1; i <= N; i++)
    {
        P[i] = 0;
    }
    P[source] = -1;

    Q.push (source);
    while (!Q.empty())
    {
        c = Q.front();
        Q.pop();

        for (i = 0; i < V[c].size(); i++)
        {
            v = V[c][i];

            if (C[c][v] - F[c][v] > 0 && P[v] == 0)
            {
                P[v] = c;
                Q.push (v);
            }
        }
    }

    if (P[sink] != 0)
        return true;
    return false;
}

void bfs2 (int N, int *P, int **C, int **F, int start, int val)
{
    int n, v;
    queue <int> Q;

    P[start] = val;
    Q.push (start);

    while (!Q.empty())
    {
        n = Q.front ();
        Q.pop ();

        for (int i = 0; i < V[n].size(); i++)
        {
            v = V[n][i];
            if (((C[n][v] > F[n][v] && F[n][v] >= 0 && val == 1) || (C[v][n] > F[v][n] && F[v][n] >= 0 && val == 2)) && P[v] == 0)
            {
                P[v] = val;
                Q.push (v);
            }
        }
    }
}

void flow (int N, int **C)
{
    int minflow, leaf, n, p, i, j;
    int *P = (int *) malloc (sizeof (int) * (N + 1));
    int **F = (int **) malloc (sizeof (int *) * (N + 1));
    for (i = 1; i <= N; i++)
        F[i] = (int *) malloc (sizeof (int) * (N + 1));
    for (i = 1; i <= N; i++) for (j = 1; j <= N; j++) F[i][j] = 0;


    while (bfs (N, P, C, F))
    {
        bool cont = 0;

        for (i = 0; i < V[sink].size(); i++)
        {
            leaf = V[sink][i];
            if (P[leaf] == 0)
                continue;

            minflow = C[leaf][sink] - F[leaf][sink];
            for (n = sink, p = leaf; n != source; n = (n == sink ? leaf : P[n]), p = P[p])
                minflow = min (minflow, C[p][n] - F[p][n]);

            if (minflow == 0)
                continue;
            cont = 1;

            for (n = sink, p = leaf; n != source; n = (n == sink ? leaf : P[n]), p = P[p])
            {
                F[p][n] += minflow;
                F[n][p] -= minflow;
            }
        }
        if (cont == 0)
            break;
    }

    for (i = 1; i <= N; i++) P[i] = 0;
    bfs2 (N, P, C, F, source, 1);
    bfs2 (N, P, C, F, sink, 2);

    int count = 0;

    for (i = 1; i <= N; i++)
    {
        for (j = 1; j <= N; j++)
        {
            //if (I[i][j]) cout << i << ',' << j << " -> " << " Cap " << C[i][j] << ", Flux " << F[i][j] << ", Index " << I[i][j] << '\n';
            if (I[i][j] && C[i][j] == F[i][j] && P[i] + P[j] == 3)
            {
                count++;
            }
        }
    }

    fo << count << '\n';

    /*
    cout << "\n\n\n";
    for (i = 1; i <= N; i++)
        cout << P[i] << ' ';
    cout << "\n\n\n";
    */

    for (i = 1; i <= N; i++)
    {
        for (j = 1; j <= N; j++)
        {
            if (I[i][j] && C[i][j] == F[i][j] && P[i] + P[j] == 3)
            {
                //cout << " --------> (" << i << ',' << j << ") <-------- \n";
                fo << I[i][j] << '\n';
            }
        }
    }
}

int main()
{
    int N, M;
    int **C;

    read (N, M, C);
    flow (N, C);

    return 0;
}