Cod sursa(job #1966335)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 15 aprilie 2017 10:10:18
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.73 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;
ifstream in("critice.in");
ofstream out("critice.out");

#define pb push_back
const int NMax = 1e3 + 5;
const int MMax = 1e4 + 5;
const int inf = 2e9 + 5;

int N,M;
int cap[NMax][NMax],dad[NMax];
bool fromS[NMax],toT[NMax];
vector<int> v[NMax];
// cap[i][j] = capacitatea ramasa pe arcul (i,j)
// dad[i] = nodul precedent nodului i in parcurgerea bfs curenta a algoritmului Edmonds-Karp
// fromS[i] = true daca se poate ajunge de la sursa la nodul i in parcurgerea bfs curenta
// toT[i] = true daca se poate ajunge de la la nodul i la destinatie in parcurgerea bfs curenta
// v - lista de adiacenta

struct elem {
    int x,y,id;
    elem(int _x = 0,int _y = 0,int _id = 0) {
        x = _x; y = _y; id = _id;
    }
};
vector<elem> muchii;
vector<int> sol;
// muchii - retine muchiile din input
// sol - retine id-urile muchiile din input care sunt tunele critice

bool bfs(int,int,bool*);
void afterBfs(int,bool*);

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

        cap[x][y] = cap[y][x] = c;
        muchii.pb(elem(x,y,i));
        v[x].pb(y);
        v[y].pb(x);
    }

    // algoritmul Edmonds-Karp
    //int maxFl = 0;
    while ( bfs(1,N,fromS) ) {

        for (int k=0;k < (int)v[N].size();++k) {
            int pre = v[N][k];
            if (!fromS[pre] || !cap[pre][N]) {
                continue;
            }

            dad[N] = pre;
            int nod = N,mnCap = inf;
            while (nod != 1) {
                mnCap = min(mnCap,cap[dad[nod]][nod]);
                nod = dad[nod];
            }

            if (!mnCap) {
                continue;
            }

            nod = N;
            while (nod != 1) {
                cap[dad[nod]][nod] -= mnCap;
                cap[nod][dad[nod]] += mnCap;
                nod = dad[nod];
            }

            //maxFl += mnCap;
        }
    }
    //cout<<maxFl<<'\n';

    // construieste toT
    afterBfs(N,toT);

    // o muchie este tunel critic daca se poate ajunge de la sursa la el si de la el la destinatie
    // dupa determinarea fluxului maxim
    for (int k=0;k < (int)muchii.size();++k) {
        int x = muchii[k].x;
        int y = muchii[k].y;
        if ( (cap[x][y] == 0 && fromS[x] && toT[y]) ||
             (cap[y][x] == 0 && fromS[y] && toT[x])    ) {

            sol.pb(muchii[k].id);
        }
    }

    out<<sol.size()<<'\n';
    for (int k=0;k <(int)sol.size();++k) {
        out<<sol[k]<<'\n';
    }

    in.close();out.close();
    return 0;
}

bool bfs(int source,int dest,bool *viz) {
    for (int i=2;i<=N;++i) {
        viz[i] = false;
    }
    viz[1] = true;
    queue<int> Q;
    Q.push(1);
    bool reachedN = false;
    while (Q.size()) {
        int nod = Q.front();
        Q.pop();
        if (nod == N) {
            reachedN = true;
            continue;
        }

        for (int k=0;k < (int)v[nod].size();++k) {
            int next = v[nod][k];
            if (viz[next] || !cap[nod][next]) {
                continue;
            }

            viz[next] = true;
            dad[next] = nod;
            Q.push(next);
        }
    }
    return reachedN;
}

void afterBfs(int source,bool* viz) {

    viz[source] = true;
    queue<int> Q;
    Q.push(source);
    while (Q.size()) {
        int nod = Q.front();
        Q.pop();

        for (int k=0;k < (int)v[nod].size();++k) {
            int next = v[nod][k];
            if (viz[next] || !cap[next][nod]) {
                continue;
            }

            viz[next] = true;
            Q.push(next);
        }
    }
}