Cod sursa(job #2230765)

Utilizator Y0da1NUME JMECHER Y0da1 Data 11 august 2018 13:43:59
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>


#define MAXN 1024
#define maxn 1024
#define NMAX 1024   //nimeresc si eu una

const int INF = 2e9;

using namespace std;

vector <int> G[maxn];
queue <int> Q;
int N, M;
int cost[maxn][maxn];
int flux[NMAX][NMAX];
int vizitat[maxn];
int precedent[maxn];
int scoruri[maxn];
pair <int, int> muchii [10*maxn];
vector<int> ans;

void clear_q()
{
    while(!Q.empty())
        Q.pop();
}

int BEFEU()
{
    clear_q();
    Q.push(1);
    for(int i = 0; i < NMAX; ++i)
        vizitat[i] = 0;
    vizitat[1] = 1;
    while(!Q.empty())
    {
        int cur = Q.front();
        Q.pop();
        if(cur == N)
            continue;
        for(int j = 0; j < G[cur].size(); ++j)
        {
            int vecin = G[cur][j];
            if(vizitat[vecin] || cost[cur][vecin] == flux[cur][vecin])
                continue;
            vizitat[vecin] = 1;
            precedent[vecin] = cur;
            Q.push(vecin);
        }
    }

    return vizitat[N];
}

void DEFEU(int cur, int scor)   //ideea e sa nu parcurgem muchiile "bottleneck". Vom apela defeul de 2 ori (de la ca si de la coada) si bottlenekurile vor avea capetele marcate cu scoruri diferite
{
    scoruri[cur] = scor;
    for (int i = 0; i < G[cur].size(); ++i)
    {
        int vecin = G[cur][i];
        if(!scoruri[vecin])
            if(flux[cur][vecin] < cost[cur][vecin] && flux[vecin][cur] < cost[vecin][cur])
                DEFEU(vecin, scor);
    }
}
int main()
{
    ifstream in ("critice.in");
    ofstream out ("critice.out");
    in>>N>>M;
    for(int i = 0; i < M; ++i)
    {
        int x, y, flow;
        in>>x>>y>>flow;
        G[x].push_back(y);
        G[y].push_back(x);
        cost[x][y] = flow;
        cost[y][x] = flow;
        muchii[i].first = x;
        muchii[i].second = y;
    }

    int nod, flow, fmin, sol = 0;

    while (BEFEU())
    for(int i = 0; i < G[N].size(); ++i)
    {
        nod = G[N][i];
        if (flux[nod][N] == cost[nod][N] || !vizitat[nod])
            continue;
        precedent[N] = nod;

        fmin = INF;
        for (nod = N; nod != 1; nod = precedent[nod])   //gasim bottleneckul
            fmin = min(fmin, cost[precedent[nod]][nod] - flux[precedent[nod]][nod]);    ///gasim bottleneckul

        for (nod = N; nod != 1; nod = precedent[nod])   //aplicam bottleneckul
            {
                flux[precedent[nod]][nod] += fmin;
                flux[nod][precedent[nod]] -= fmin;
            }
        flow+=fmin;
    }

    //cout<<flow;   //verificare pt maxflow

    DEFEU(1, 1);    //marcam cu alba-neagra
    DEFEU(N, 2);
    for(int i = 0; i < M; ++i)
    {
        int st = muchii[i].first;
        int dr = muchii[i].second;
        if(scoruri[st] && scoruri[dr])
            if(scoruri[st] != scoruri[dr])
            {
                ++sol;
                ans.push_back(i + 1);
            }
    }

    cout<<"Sunt "<<sol<<" bottleneckuri:\n";
    out<<sol<<"\n";

    for(int i = 0; i < sol; ++i)
    {
        cout<<ans[i]<<" ";
        out<<ans[i]<<"\n";
    }

    return 0;
}