Cod sursa(job #3328163)

Utilizator Nasa1004Ema Nicole Gheorghe Nasa1004 Data 6 decembrie 2025 15:54:36
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.03 kb
#include <fstream>
#include <bitset>
#include <vector>
#include <queue>

using namespace std;
const int NMAX = 1000;
const int MMAX = 10000;

ifstream cin("critice.in");
ofstream cout("critice.out");

struct nod_flux{
    int nod;
    int cap;
    int flux;
    int pereche;
};
vector <vector <nod_flux>> v;
int n;

struct muchii{
    int nod1, nod2, cap;
}edge[MMAX + 2];

void add(muchii x) { ///avem in ambele directii
    if(x.nod1 > x.nod2)
        swap(x.nod1, x.nod2);
    v[x.nod1].push_back({x.nod2, x.cap, 0, -1});
    v[x.nod2].push_back({x.nod1, x.cap, 0, -1});
    v[x.nod1].back().pereche = v[x.nod2].size() - 1;
    v[x.nod2].back().pereche = v[x.nod1].size() - 1;

    if(x.nod1 == 1) ///NU ne ducem inapoi la 1
        v[x.nod2].back().cap = 0;
    if(x.nod2 == n) ///NU iesim din destinatie
        v[x.nod2].back().cap = 0;
}

bitset <NMAX + 2> viz;
pair <int, int> tata[NMAX + 2]; ///tata, muchie
bool bfs() {
    viz = 0;
    viz[1] = 1; ///sursa!!
    queue <int> q;
    q.push(1);
    while(!q.empty()) {
        int now = q.front();
        q.pop();
        for(int i = 0; i < v[now].size(); i++) {
            nod_flux x = v[now][i];
            if(!viz[x.nod] && x.flux < x.cap) {
                viz[x.nod] = 1;
                tata[x.nod] = {now, i};
                q.push(x.nod);
            }
        }
    }
    return viz[n]; ///destinatia!!!
}

int recons(int start, int minn) {
    while(tata[start].first) {
        minn = min(minn, v[tata[start].first][tata[start].second].cap - v[tata[start].first][tata[start].second].flux);
        start = tata[start].first;
        if(minn <= 0)
            return minn;
    }
    return minn;
}

void change(int a, int b, int muchie, int val) {
    v[a][muchie].flux += val;
    v[b][v[a][muchie].pereche].flux -= val;
}

void update(int start, int val) {
    while(tata[start].first) {
        change(tata[start].first, start, tata[start].second, val);
        start = tata[start].first;
    }
}

bitset <NMAX + 2> b[2];
void bfsAccesibil(int start, bool tip) {
    queue <int> q;
    b[tip][start] = 1;
    q.push(start);
    while(!q.empty()) {
        int now = q.front();
        q.pop();
        for(auto x : v[now]) {
            if(b[tip][x.nod])
                continue;
            if(!tip) { ///pe normal
                    if(x.flux < x.cap) {
                        b[0][x.nod] = 1;
                        q.push(x.nod);
                    }
            }
            else {
                if(v[x.nod][x.pereche].flux < v[x.nod][x.pereche].cap) {
                    b[1][x.nod] = 1;
                    q.push(x.nod);
                }
            }
        }
    }
}

int main() {
    int m;
    cin >> n >> m;
    v.resize(n + 1);
    for(int i = 1; i <= m; i++) {
        cin >> edge[i].nod1 >> edge[i].nod2 >> edge[i].cap;
        add(edge[i]);
    }
    ///facem fluxul
    while(bfs()) {
        for(int i = 0; i < v[n].size(); i++) {
            nod_flux x = v[n][i];
            if(viz[x.nod] && v[x.nod][x.pereche].flux < v[x.nod][x.pereche].cap) {
                int add = recons(x.nod, v[x.nod][x.pereche].cap - v[x.nod][x.pereche].flux);
                if(add > 0) {
                    change(x.nod, n, x.pereche, add);
                    update(x.nod, add);
                }
            }
        }
    }
    /*for(int i = 1; i <= n; i++) {
        cout << "Nodul " << i << '\n';
        for(auto x : v[i])
            cout << x.nod << "  " << x.flux << "/" << x.cap << "  " << x.pereche << "\n";
    }*/
    bfsAccesibil(1, 0);
    bfsAccesibil(n, 1);
    /*for(int j = 0; j <= 1; j++) {
        for(int i = 1; i <= n; i++) {
            if(b[j][i])
                cout << i << " ";
        }
        cout << '\n';
    }*/
    int cnt = 0;
    for(int i = 1; i <= m; i++) {
        if((b[0][edge[i].nod1] && b[1][edge[i].nod2]) || (b[1][edge[i].nod1] && b[0][edge[i].nod2]))
            cnt++;
    }
    cout << cnt << '\n';
    for(int i = 1; i <= m; i++) {
        if((b[0][edge[i].nod1] && b[1][edge[i].nod2]) || (b[1][edge[i].nod1] && b[0][edge[i].nod2]))
            cout << i << '\n';
    }
    return 0;
}