Cod sursa(job #1967334)

Utilizator mariakKapros Maria mariak Data 16 aprilie 2017 14:53:51
Problema Critice Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.55 kb
#include <bits/stdc++.h>
#define maxN 1002
#define inf (1 << 30)
/* muchii critice (muchii a caror capacitate daca este marita implica o crestere de flux)
   nu pot fi decat muchiile saturate(se garanteaza din propr alg de flux;
   in plus nu toate muchiile saturate sunt muchii critice ci doar cele care fac parte dintr-un
   drum de ameliorare*/

FILE *fin  = freopen("critice.in", "r", stdin);
FILE *fout = freopen("critice.out", "w", stdout);

using namespace std;
int N, M, S, D;
vector <int> G[maxN];
int r[maxN][maxN], dad[maxN], m[maxN][maxN];
vector <int> sol;
bool vis[2][maxN];
queue <int> q;

bool bfs(){
    for(int i = 1; i <= N; ++ i)
        dad[i] = 0;
    dad[S] = S;
    q.push(S);
    while(!q.empty()){
        int node = q.front();
        q.pop();
        for(int son : G[node]){
            if(!r[node][son] || dad[son]) continue;
            dad[son] = node;
            if(son != D) q.push(son);
        }
    }
    return dad[D] != 0;
}

void dfs(int node, bool dir){
    for(int son : G[node])
        if (r[node][son] > 0 && !vis[dir][son]){
            vis[dir][son] = 1;
            dfs(son, dir);
        }
}

void Flow(){
    while(bfs()){
        for(int node : G[D])
            if(dad[node]){
                dad[D] = node;
                int pathFlow = inf;
                node = D;
                while(node != S){
                    pathFlow = min(pathFlow, r[dad[node]][node]);
                    node = dad[node];
                }
                node = D;
                while(node != S){
                    r[dad[node]][node] -= pathFlow;
                    r[node][dad[node]] += pathFlow;
                    node = dad[node];
                }
            }
    }
}

void solution(){
    vis[0][1] = 1;
    dfs(1, 0);
    vis[1][N] = 1;
    dfs(N, 1);
    for(int i = 1; i <= N; ++ i)
        for(int j = 1; j <= N; ++ j)
            if(!r[i][j] && m[i][j] && ((vis[0][i] && vis[1][j]) || (vis[1][i] && vis[0][j])))
                sol.push_back(m[i][j]);
    sort(sol.begin(), sol.end());
    sol.erase(unique(sol.begin(), sol.end()), sol.end());
    printf("%d\n", (int) sol.size());
    for(int edge : sol)
        printf("%d\n", edge);
}

int main(){
    scanf("%d %d", &N, &M);
    for(int i = 1; i <= M; ++ i){
        int x, y, c;
        scanf("%d %d %d", &x, &y, &c);
        r[x][y] = r[y][x] = c;
        m[x][y] = m[y][x] = i;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    S = 1, D = N;
    Flow();
    solution();
    return 0;
}