Cod sursa(job #883935)

Utilizator Stefex09Stefan Teodorescu Stefex09 Data 20 februarie 2013 15:46:15
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

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

const int MAXN = 1010;

int N, M;
vector <int> Graf[MAXN];
vector <int> Sol;
struct muchie {int x, y;} V[10 * MAXN];
int C[MAXN][MAXN], F[MAXN][MAXN];
bool Viz[MAXN];
bool Mark1[MAXN], MarkN[MAXN];
int T[MAXN];

void Read ()
{
    int a, b, c, i;

    in >> N >> M;

    for (i = 1; i <= M; i ++){
        in >> a >> b >> c;

        V[i] = {a, b};
        Graf[a].push_back (b);
        Graf[b].push_back (a);
        C[a][b] += c;
        C[b][a] += c;
    }
}

inline bool BFS ()
{
    vector <int> :: iterator it;
    queue <int> Q;
    memset (Viz, 0, sizeof (Viz));
    int nod;

    Q.push (1);

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

        if (nod == N)
            continue;

        Viz[nod] = 1;

        for (it = Graf[nod].begin (); it != Graf[nod].end (); ++ it)
            if (!Viz[*it] && C[nod][*it] != F[nod][*it]){
                Viz[*it] = 1;
                T[*it] = nod;
                Q.push (*it);
        }
    }

    return Viz[N];
}

void Augment ()
{
    vector <int> :: iterator it;
    int nod, fmin;

    for ( ; BFS (); )
        for (it = Graf[N].begin (); it != Graf[N].end (); ++ it){
            if (!Viz[*it] || C[*it][N] == F[*it][N])
                continue;

            fmin = (1 << 30);
            T[N] = *it;

            for (nod = N; nod != 1; nod = T[nod])
                fmin = min (fmin, C[ T[nod] ] [nod] - F[ T[nod] ][nod]);

            if (!fmin)
                continue;

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

void Mark (bool *Viz, int nod, bool dir)
{
    vector <int> :: iterator it;
    Viz[nod] = 1;

    for (it = Graf[nod].begin (); it != Graf[nod].end (); ++ it){
        if (!Viz[*it] && dir == 0 && C[nod][*it] > F[nod][*it])
            Mark (Viz, *it, dir);

        if (!Viz[*it] && dir == 1 && C[*it][nod] > F[*it][nod])
            Mark (Viz, *it, dir);
    }
}

void Solve ()
{
    Augment ();
    Mark (Mark1, 1, 0);
    Mark (MarkN, N, 1);

    int nod1, nod2, i;

    for (i = 1; i <= M; i ++){
        nod1 = V[i].x;
        nod2 = V[i].y;
        if (C[nod1][nod2] == F[nod1][nod2] && Mark1[nod1] && MarkN[nod2])
            Sol.push_back (i);

        if (C[nod2][nod1] == F[nod2][nod1] && Mark1[nod2] && MarkN[nod1])
            Sol.push_back (i);
    }
}

void Write ()
{
    int i, N;

    N = Sol.size ();
    out << N << "\n";

    for (i = 0 ; i < N; i ++)
        out << Sol[i] << "\n";
}

int main()
{
    Read ();
    Solve ();
    Write ();

    return 0;
}