Cod sursa(job #1194476)

Utilizator mihai995mihai995 mihai995 Data 3 iunie 2014 22:43:24
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.47 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();

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

    return use[D];
}

inline int canPush(int x, int y){
    return cap[x][y] - flux[x][y];
}

inline void saturate(int x, int y, int F){
    flux[x][y] += F;
    flux[y][x] -= F;
}

void maxFlow(int S, int D){
    while (bfs(S, D))
        for (int vec : graph[D]){
            int F = canPush(vec, D);
            for (int i = vec ; i != S ; i = T[i])
                F = min(F, canPush(T[i], i));

            if (!F) continue;

            saturate(vec, D, F);
            for (int i = vec ; i != S ; i = T[i])
                saturate(T[i], i, F);
        }

    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;
}