Cod sursa(job #1194468)

Utilizator mihai995mihai995 mihai995 Data 3 iunie 2014 22:37:21
Problema Critice Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;

const int N = 1 + 1e3, M = 1 + 1e4, inf = 0x3f3f3f3f;

struct Edge{
    int x, y;
};

int cap[N][N], flux[N][N], T[N], n, nrE;
bool use[N], reachS[N], reachD[N];
vector<int> graph[N];
Edge E[M];

void scrie(){
    for (int i = 1 ; i <= n ; i++){
        for (int j = 1 ; j <= n ; j++)
            cout << flux[i][j] << " / " << cap[i][j] << '\t';
        cout << '\n';
    }
}

inline bool canGo(int x, int y){
    return flux[x][y] < cap[x][y];
}

inline bool revGo(int x, int y){
    return flux[y][x] < cap[y][x];
}

bool bfs(int x, int D, bool (*canGo)(int, int) = ::canGo){
    queue<int> Q;
    memset(use, false, sizeof(use));

    Q.push(x);
    use[x] = true;

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

        if (x == D)
            return true;

        for (auto i: graph[x])
            if (!use[i] && canGo(x, i)){
                use[i] = true;
                T[i] = x;
                Q.push(i);
            }
    }

    return false;
}

void maxFlow(int S, int D){
    while (bfs(S, D)){
        int amount = inf;
        for (int i = D ; i != S ; i = T[i])
            amount = min(amount, cap[ T[i] ][i] - flux[ T[i] ][i]);
        for (int i = D ; i != S ; i = T[i]){
            flux[ T[i] ][i] += amount;
            flux[i][ T[i] ] -= amount;
        }
    }
    memcpy(reachS, use, sizeof(use));
    bfs(D, S, revGo);
    memcpy(reachD, use, sizeof(use));
}

inline bool critEdge(Edge E){
    return ( reachS[ E.x ] && reachD[ E.y ] ) || ( reachD[ E.x ] && reachS[ E.y ] );
}

void read(const char* fin){
    ifstream in(fin);
    int C;

    in >> n >> nrE;
    for (int i = 1 ; i <= nrE ; i++){
        in >> E[i].x >> E[i].y >> C;
        cap[ E[i].x ][ E[i].y ] = cap[ E[i].y ][ E[i].x ] = C;

        graph[ E[i].x ].push_back( E[i].y );
        graph[ E[i].y ].push_back( E[i].x );
    }

    in.close();
}

void print(const char* fout){
    int cnt = 0;
    for (int i = 1 ; i <= nrE ; i++)
        cnt += critEdge( E[i] );

    ofstream out(fout);

    out << cnt << '\n';
    for (int i = 1 ; i <= n ; i++)
        if ( critEdge( E[i] ) )
            out << i << '\n';

    out.close();
}

int main(){
    read("critice.in");
    maxFlow(1, n);
    print("critice.out");

    return 0;
}