Cod sursa(job #2695001)

Utilizator ionut200328Chitu Ioan ionut200328 Data 11 ianuarie 2021 14:17:53
Problema Critice Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <iostream>
#include <fstream>
#include <queue>
#define nmax 10001
using namespace std;
int a[nmax][nmax], c[nmax][nmax], f[nmax][nmax];
int viz[nmax], T[nmax], lista[nmax];
int n, m, lung, minim;
ifstream fin("critice.in");
ofstream fout("critice.out");
struct arc { int n1, n2; };
arc drum[nmax], lungimemuchie[nmax];
int bf()
{
    int i, j;
    queue <int> q;
    fill(viz, viz + nmax, 0); fill(T, T + nmax, 0);
    q.push(1);
        viz[1] = 1;
    while (q.empty() != 1)
    {
        i = q.front();
        if (i == n)
            return 1;
        q.pop();
        for (j = 1; j <= n; j++)
        {
            if (viz[j] == 0 && c[i][j] - f[i][j] > 0)
            {//arc parcurs in sens direct
                viz[j] = 1;
                T[j] = i;
                q.push(j);
            }
            if (viz[j] == 0 && f[j][i] > 0)
            {//arc parcurs in sens invers
                viz[j] = 1;
                T[j] = i;
                q.push(j);
            }
        }
    }
    return 0;
}
void calcdrum()
{
    int i = 0, b = n, a;
    minim = 10000000;
    a = T[b];
    while (a != 0)
    {
        drum[i].n1 = a;
        drum[i].n2 = b;
        if (c[a][b] > f[a][b])
        {
            if (minim > c[a][b] - f[a][b])
                minim = c[a][b] - f[a][b];
        }
        else
            if (minim > f[b][a])
                minim = f[b][a];
        i++;
        b = a;
        a = T[b];
    }
    lung = i;
}
 
 
int main()
{
    int i, j, k, ok = 1;
    fin >> n >> m;
    for (int ct = 0; ct < m; ct++)
    {
        fin >> i >> j;
        fin >> c[i][j];
        c[j][i] = c[i][j];
        lungimemuchie[ct].n1 = i;
        lungimemuchie[ct].n2 = j; 
    }
    while (ok==1)
    {
        ok = bf(); //returneaza 1 daca gaseste un drum
        if (ok==1)
        {
            calcdrum(); //calculeaza si minimul
            //cout << "\n\ngasit un drum de lungime " << lung;
            //cout << " capacitate reziduala " << minim << endl;
            //cout << "format din arcele: ";
            for (k = 0; k < lung; k++)
            {
                i = drum[k].n1;
                j = drum[k].n2;
               //cout << i << '-' << j << " , ";
                if (c[i][j] - f[i][j] > 0)
                    f[i][j] += minim;
                else
                    f[j][i] -= minim;
            }
        }
    }
    int lungimelista = 0;
    for (int i = 0; i < m; ++i)
    {
        c[lungimemuchie[i].n2][lungimemuchie[i].n1]++;
        c[lungimemuchie[i].n1][lungimemuchie[i].n2]++;
        
        ok = bf();
        if (ok==1)
        {
            calcdrum();
            if (minim > 0)
            {
                
                lista[lungimelista] = i + 1;
                lungimelista++;
                //cout << lungimelista << endl;
            }              
        }
        c[lungimemuchie[i].n2][lungimemuchie[i].n1]--;
        c[lungimemuchie[i].n1][lungimemuchie[i].n2]--;
        
    }
    fout << lungimelista << "\n";
    for (int i = 0; i < lungimelista; ++i)
        fout << lista[i] << "\n";
    return 0;
}