Cod sursa(job #989628)

Utilizator cbanu96Banu Cristian cbanu96 Data 26 august 2013 01:00:09
Problema Critice Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.51 kb
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

const int NMAX = 1003;

#define FILEIN "critice.in"
#define FILEOUT "critice.out"

vector<int> A[NMAX];
int cap[NMAX][NMAX];
int flow[NMAX][NMAX];
int t[NMAX];
int N, M;
bool mark[NMAX];

vector<pair<int, int> > muchii;
vector<int> sol;

bool bfs() {
    queue<int> Q;
    memset(mark, 0, sizeof(mark));
    Q.push(1);

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

        if ( nod == N ) continue;
        for ( size_t j = 0; j < A[nod].size(); j++) {
            int next = A[nod][j];
            if (cap[nod][next] == flow[nod][next] || mark[next]) continue;
            mark[next] = 1;
            Q.push(next);
            t[next] = nod;
        }
    }

    return mark[N];
}

int detfmin(int nod) {
    int f = 0x3f3f3f3f;
    for ( nod = N; nod != 1; nod = t[nod]) {
        f = min(f, cap[t[nod]][nod] - flow[t[nod]][nod]);
    }
    return f;
}

void rmfmin(int nod, int f) {
    for ( nod = N; nod != 1; nod = t[nod]) {
        flow[t[nod]][nod] += f;
        flow[nod][t[nod]] -= f;
    }
}

bool bfs2(int startnode, int target) {
    queue<int> Q;
    memset(mark, 0, sizeof(mark));
    Q.push(startnode);

    while (!Q.empty()) {
        int nod = Q.front(); Q.pop();
        if (nod == target)
            return true;
        for ( size_t j = 0; j < A[nod].size(); j++) {
            int next = A[nod][j];
            if (cap[nod][next] != max(flow[nod][next], flow[next][nod]) && !mark[next]) {
                mark[next] = 1;
                if ( next == target)
                    return true;
                Q.push(next);
            }
        }
    }

    return 0;
}

int bfs3(int startnode) {
    queue<int> Q;
    memset(mark, 0, sizeof(mark));
    Q.push(startnode);

    while (!Q.empty()) {
        int nod = Q.front(); Q.pop();
        if (nod == N || nod == 1)
            return nod;
        for ( size_t j = 0; j < A[nod].size(); j++) {
            int next = A[nod][j];
            if (cap[nod][next] != max(flow[nod][next], flow[next][nod]) && !mark[next]) {
                mark[next] = 1;
                if ( next == N || next == 1)
                    return next;
                Q.push(next);
            }
        }
    }

    return 0;
}

int main() {
    freopen(FILEIN, "r", stdin);
    freopen(FILEOUT, "w", stdout);

    scanf("%d %d", &N, &M);
    for ( int i = 1, x, y, z; i <= M; i++ ) {
        scanf("%d %d %d", &x, &y, &z);
        cap[x][y] = z;
        cap[y][x] = z;
        A[x].push_back(y);
        A[y].push_back(x);
        muchii.push_back(make_pair(x,y));
    }

    /** Flux */

    while(bfs()) {
        for ( int i = 0; i < A[N].size(); i++) {
            int nod = A[N][i];
            if (flow[nod][N] == cap[nod][N] || !mark[nod]) continue;
            t[N] = nod;

            int fminim = detfmin(nod);
            if (!fminim)
                continue;

            rmfmin(nod, fminim);
        }
    }

    for ( int i = 0, x, y; i < muchii.size(); i++ ) {
        x = muchii[i].first;
        y = muchii[i].second;
        if (max(flow[x][y], flow[y][x]) == cap[x][y]) {
            int nod = bfs3(x);
            if ( (nod == 1 && bfs2(y, N)) || (nod == N && bfs2(y, 1)))
                sol.push_back(i+1);
        }
    }

    printf("%d\n", sol.size());
    for ( int i = 0; i < sol.size(); i++) {
        printf("%d\n", sol[i]);
    }

    return 0;
}