Cod sursa(job #864911)

Utilizator vendettaSalajan Razvan vendetta Data 25 ianuarie 2013 20:54:40
Problema Critice Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.27 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

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

#define nmax 1005
#define Mmax 10005
#define ll long long
#define inf (1<<30)

int n, m, t[nmax];
bool viz[nmax], alb[nmax], negru[nmax];
queue< int > q;
vector< int> gf[nmax],rez;
int capac[nmax][nmax], flux[nmax][nmax];
pair<int,int> M[Mmax];

void citeste(){
    f >> n >> m;
    int x, y, z;
    for(int i=1; i<=m; ++i){
        f >> x >> y >> z;
        capac[x][y] = z;
        capac[y][x] = z;
        gf[x].push_back(y);
        gf[y].push_back(x);
        M[i] = make_pair(x, y);
    }
}

inline bool bfs(){
    for(int i=1; i<=n; ++i) viz[i] = 0, t[i] = 0;
    for(; q.size(); q.pop());

    q.push(1); viz[1] = 1;
    for(; q.size(); ){
        int nod = q.front(); q.pop();
        for(int i=0; i<gf[nod].size(); ++i){
            int vc = gf[nod][i];
            if (viz[vc] == 0 && capac[nod][vc] > flux[nod][vc]){
                t[vc] = nod;
                viz[vc] = 1; q.push(vc);
                if (vc == n) return 1;
            }
        }
    }

    return 0;
}

void bfsMarc(int nod, bool v[], int cod){// daca cod = 0 sunt din sursa spre destinatie
    for(int i=0; i<=n; ++i) v[i] = 0;
    for(; q.size(); q.pop());
    v[nod] = 1; q.push(nod);
    for(; q.size(); ){
        int nod = q.front(); q.pop();
        for(int i=0; i<gf[nod].size(); ++i){
            int vc = gf[nod][i];
            if (v[vc] == 1) continue;
            if (cod == 0){// am nod - > vc;
                if (capac[nod][vc] > flux[nod][vc]) v[vc] = 1, q.push(vc);
            }else {// acum pornesc din destinatie dar pompez flux pe vc -> nod
                if (capac[vc][nod] > flux[vc][nod]) v[vc] = 1, q.push(vc);
            }
        }
    }
}

void rezolva(){
    // ideea e asa : bag un flux maxim iar apoi vreau sa vad acele muchii care sunt saturate si care sunt accesibile din sursa si din destinatie
    // evident sa ajung la muchia asta doar pe muchii pe care mai pot baga flux
    for(; bfs(); ){
        int Min = inf;// aleg fluxul pe drumul curent
        for(int i=n; t[i]!=0; i=t[i]){
            //am muchia t[i] -> i
            Min = min( Min, capac[ t[i] ][i] - flux[ t[i] ][i]);
        }

        //bag fluxul pe drumul curent
        for(int i=n; t[i]!=0; i=t[i]){
            // m-am dus pe muchia t[i]->i
            flux[ t[i] ][i] += Min;// bag flux
            flux[ i ][ t[i] ] -= Min;// il intorc;
        }
    }
    // acum marchez nodurile accesibile din destinatie si din sursa mergand doar pe muchii nesaturate
    bfsMarc(1, alb, 0);
    bfsMarc(n, negru, 1);
    // acum vad muchiile saturate care au capatele accesibile din sursa si din destinatie
    for(int i=1; i<=m; ++i){
        int X = M[i].first; int Y = M[i].second;
        if ( ( (alb[X] == 1 && negru[Y] == 1 && capac[X][Y] == flux[X][Y]) || (alb[Y] == 1 && negru[X] == 1 && flux[Y][X] == capac[Y][X]) ) ){
            rez.push_back(i);
        }
    }

    g << rez.size() <<"\n";
    for(int i=0; i<rez.size(); ++i){
        g << rez[i] << "\n";
    }
}

int main(){
    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;
}