Cod sursa(job #880967)

Utilizator deneoAdrian Craciun deneo Data 17 februarie 2013 16:01:35
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <ctime>
#include <cstdlib>
using namespace std;

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

#define MAXN 1100
#define MAXM 11000
#define INF 0x3f3f3f3f
#define FORIT(it, v) for(typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)

int N, M, F[MAXN][MAXN], C[MAXN][MAXN], dad[MAXN], mark1[MAXN], mark2[MAXN], sol[MAXM];
int coada[MAXN];
vector<int> graph[MAXN];
vector< pair<int, int> > edges;

int DFS() {
    memset(dad, 0, sizeof(dad));

    coada[0] = 1; coada[1] = 1; dad[1] = 1;

    while (coada[0]) {
        int poz = (rand() % coada[0]) + 1;
        int nod = coada[poz];

        swap(coada[coada[0]], coada[poz]);
        --coada[0];

        if (nod == N)
            continue;

        FORIT(it, graph[nod])
            if (!dad[*it] && C[nod][*it] - F[nod][*it]) {
                coada[++coada[0]] = *it;
                dad[*it] = nod;
            }
    }

    return dad[N];
}

void markNodes(int nod, int mark[MAXN], int dir) {
    mark[nod] = 1;

    FORIT(it, graph[nod])
        if (!mark[*it] && ((dir == 1 && C[nod][*it] > F[nod][*it]) || (dir == 2 && C[*it][nod] > F[*it][nod])))
            markNodes(*it, mark, dir);
}

int main () {
    fin >> N >> M;

    srand(time(NULL));

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

        fin >> x >> y >> c;

        edges.push_back(make_pair(x, y));

        graph[x].push_back(y);
        graph[y].push_back(x);

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

    while (DFS()) {
        FORIT(it, graph[N])
            if (dad[*it] && C[*it][N] > F[*it][N]) {
                int minim = INF;
                dad[N] = *it;

                for (int i = N; i > 1; i = dad[i])
                    minim = min (minim, C[dad[i]][i] - F[dad[i]][i]);
                for (int i = N; i > 1; i = dad[i]) {
                    F[dad[i]][i] += minim;
                    F[i][dad[i]] -= minim;
                }
            }
    }

    markNodes(1, mark1, 1);
    markNodes(N, mark2, 2);

    FORIT(it, edges) {
        int nod1 = (*it).first;
        int nod2 = (*it).second;

        if (C[nod1][nod2] == F[nod1][nod2] && mark1[nod1] && mark2[nod2])
            sol[++sol[0]] = it - edges.begin() + 1;
        if (C[nod2][nod1] == F[nod2][nod1] && mark1[nod2] && mark2[nod1])
            sol[++sol[0]] = it - edges.begin() + 1;
    }

    fout << sol[0] << "\n";

    for (int i = 1; i <= sol[0]; ++i)
        fout << sol[i] << "\n";

    return 0;
}