Cod sursa(job #1942217)

Utilizator Burbon13Burbon13 Burbon13 Data 27 martie 2017 21:13:36
Problema Critice Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;

const int nmx = 1002;
const int inf = 0x3f3f3f3f;

int n,m,capacitate[nmx][nmx],flux[nmx][nmx],nrm[nmx][nmx],tata[nmx];
bool vizs[nmx], vizn[nmx];
vector <int> g[nmx], ans;
bitset <nmx> viz1;
queue <int> q;

void citire()
{
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= m; ++i)
    {
        int nod1,nod2,cap;
        scanf("%d %d %d", &nod1, &nod2, &cap);
        g[nod1].push_back(nod2);
        g[nod2].push_back(nod1);
        capacitate[nod1][nod2] = capacitate[nod2][nod1] = cap;
        nrm[nod1][nod2] = nrm[nod2][nod1] = i;
    }
}

bool bfs()
{
    viz1.reset();
    viz1[1] = true;
    q.push(1);

    while(not q.empty())
    {
        int nod = q.front();
        q.pop();

        if(nod == n)
            continue;

        for(vector<int>::iterator it = g[nod].begin(); it != g[nod].end(); ++it)
            if(not viz1[*it] && capacitate[nod][*it] > flux[nod][*it])
            {
                viz1[*it] = true;
                tata[*it] = nod;
                q.push(*it);
            }
    }

    return viz1[n];
}

void flux_max()
{
    while(bfs())
        for(vector<int>::iterator it = g[n].begin(); it != g[n].end(); ++it)
        {
            if(capacitate[*it][n] == flux[*it][n] || not viz1[*it])
                continue;
            tata[n] = *it;

            int minim = inf, nod = n;
            while(nod > 1)
            {
                minim = min(minim,capacitate[tata[nod]][nod] - flux[tata[nod]][nod]);
                nod = tata[nod];
            }

            nod = n;
            while(nod > 1)
            {
                flux[tata[nod]][nod] += minim;
                flux[nod][tata[nod]] -= minim;
                nod = tata[nod];
            }

        }
}

void bfs(int nod_start, bool vz[])
{
    q.push(nod_start);
    vz[nod_start] = true;

    while(not q.empty())
    {
        int nod = q.front();
        q.pop();

        for(vector<int>::iterator it = g[nod].begin(); it != g[nod].end(); ++it)
            if(not vz[*it] && flux[nod][*it] != capacitate[nod][*it])
            {
                vz[*it] = true;
                q.push(*it);
            }

    }
}

bool diferit(int nod1, int nod2)
{
    return (viz1[nod1] && vizn[nod2]) || (vizn[nod1] && viz1[nod2]);
}

void gasire()
{
    for(int i = 1; i <= n; ++i)
    {
        for(vector<int>::iterator it = g[i].begin(); it != g[i].end(); ++it)
            if(nrm[i][*it] && diferit(i,*it))
            {
                ans.push_back(nrm[i][*it]);
                nrm[i][*it] = nrm[*it][i] = 0;
            }
    }
}

void afish()
{
    printf("%d\n", ans.size());
    for(auto i: ans)
        printf("%d\n", i);
}

int main()
{
    freopen("critice.in", "r", stdin);
    freopen("critice.out", "w", stdout);
    citire();
    flux_max();
    bfs(1,vizs);
    bfs(n,vizn);
    gasire();
    afish();
    return 0;
}