Cod sursa(job #1915359)

Utilizator FloareaCucura Floarea Ludovica Floarea Data 8 martie 2017 20:45:18
Problema Critice Scor 100
Compilator cpp Status done
Runda becreative29 Marime 2.48 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
#include <algorithm>
#include <utility>
#include <string.h>


using namespace std;

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

typedef vector<int>::iterator It;
const int MaxN=1005, MaxM=10005, Inf=0x3f3f3f3f;
int N, M, C[MaxN][MaxN], F[MaxN][MaxN], Father[MaxN];
vector<int> G[MaxN];
bitset <MaxN> Used, Source, Sink;
queue <int> Q, Critic;
pair<int, int> Vertex[MaxM];

bool BFs() {
    int Node;
    Used.reset();
    for(Q.push(1), Node = 1, Used[Node] = true ; !Q.empty() ; Q.pop(), Node = Q.front())
        for(It it = G[Node].begin(), fin = G[Node].end() ; it != fin ; ++ it)
            if(!Used[*it] && F[Node][*it] < C[Node][*it])
                Used[*it] = true, Q.push(*it), Father[*it] = Node;
    return Used[N];
}
void BFs(int Node, bitset<MaxN> &Use){
    for(Q.push(Node), Use[Node] = true; !Q.empty() ; Q.pop(), Node = Q.front())
        for(It it = G[Node].begin(), fin = G[Node].end(); it != fin ; ++ it)
            if(!Use[*it] && (C[Node][*it] >  (F[Node][*it] < 0 ? -F[Node][*it] : F[Node][*it])))
                Use[*it] = true, Q.push(*it);
}
int main() {
    fin>>N>>M;
    for(int i=1;i<=M;++i)
        {
            int x, y, z;
            fin>>x>>y>>z;
            G[x].push_back(y);
            G[y].push_back(x);
            C[x][y]=C[y][x]=z;
            Vertex[i]={x,y};
        }
    for( ; BFs() ;) {
        int MinFlow=Inf;
        for(int i = 1 ; i < N ; ++ i)
            if(F[i][N] < C[i][N]) {
                int MinFlow = C[i][N] - F[i][N];
                for(int j = i ; j != 1 ; j = Father[j])
                    MinFlow = min(MinFlow, C[Father[j]][j] - F[Father[j]][j]);
                for(int j = i ; j != 1 ; j = Father[j])
                    F[Father[j]][j] += MinFlow,
                    F[j][Father[j]] -= MinFlow;
                F[i][N] += MinFlow;
                F[N][i] -= MinFlow;
            }
    }
    BFs(1, Source);
    BFs(N, Sink);

    for(int i = 1 ; i <= M ; ++ i) {
        int Node1 = Vertex[i].first, Node2 = Vertex[i].second;
        if((Source[Node1] && Sink[Node2]) || (Sink[Node1] && Source[Node2]))
            if(C[Node1][Node2] == F[Node1][Node2] || C[Node2][Node1] == F[Node2][Node1])
                Critic.push(i);
    }
    for(fout << Critic.size() <<"\n" ; !Critic.empty() ; Critic.pop())
        fout << Critic.front() << "\n";
    fin.close();
    fout.close();
    return 0;
}