Cod sursa(job #2794059)

Utilizator vladth11Vlad Haivas vladth11 Data 4 noiembrie 2021 11:45:06
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.2 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <long double, pii> muchie;

const ll NMAX = 5001;
const ll VMAX = 21;
const ll INF = 2e9;
const ll MOD = 1000000009;
const ll BLOCK = 318;
const ll base = 31;
const ll nr_of_bits = 21;

vector <int> v[NMAX];
int nrEdges;
int n;

struct edge{
    int from, to, cap, init, idx;
}e[40001];

int invers(int x){
    if(x & 1)
        return x + 1;
    return x - 1;
}

void addEdge(int a, int b, int c, int idx){
    v[a].push_back(++nrEdges);
    e[nrEdges] = {a, b, c, c, idx};
    v[b].push_back(++nrEdges);
    e[nrEdges] = {b, a, c, c, idx};
}

vector <int> nou[NMAX], invnou[NMAX];
int sourceR[NMAX], sinkR[NMAX];

void sourceD(int node){
    sourceR[node] = 1;
    for(auto x : nou[node]){
        if(!sourceR[x]){
            sourceD(x);
        }
    }
}

void sinkD(int node){
    sinkR[node] = 1;
    for(auto x : invnou[node]){
        if(!sinkR[x]){
            sinkD(x);
        }
    }
}

int last[NMAX];

bool bfs(){
    int i;
    for(i = 1; i <= n; i++)
        last[i] = -1;
    last[1] = 0;
    queue <int> q;
    q.push(1);
    while(q.size()){
        int node = q.front();
        q.pop();
        for(auto x : v[node]){
            if(last[e[x].to] != -1 || e[x].cap == 0){
                continue;
            }
            if(e[x].to == n)
                return 1;
            q.push(e[x].to);
            last[e[x].to] = x;
        }
    }
    return 0;
}

void getFlow(){
    while(bfs()){
        for(auto x : v[n]){
            if(last[e[x].to] == -1 || e[invers(x)].cap == 0){
                continue;
            }
            int minim = e[invers(x)].cap;
            int node = e[x].to;
            while(last[node] > 0){
                minim = min(minim, e[last[node]].cap);
                node = e[last[node]].from;
            }
            e[invers(x)].cap -= minim;
            e[x].cap += minim;
            node = e[x].to;
            while(last[node] > 0){
                e[last[node]].cap -= minim;
                e[invers(last[node])].cap += minim;
                node = e[last[node]].from;
            }
        }
    }
}

int main() {
    ifstream cin("critice.in");
    ofstream cout("critice.out");
    int m, i;
    cin >> n >> m;
    for(i = 1; i <= m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        addEdge(a, b, c, i);
    }
    getFlow();
    vector <int> verif, sol;
    for(i = 1; i <= nrEdges; i++){
        if(e[i].cap != 0){
            nou[e[i].from].push_back(e[i].to);
            invnou[e[i].to].push_back(e[i].from);
        }else{
            verif.push_back(i);
        }
    }
    sourceD(1);
    sinkD(n);
    for(auto x : verif){
        if(sourceR[e[x].from] && sinkR[e[x].to]){
            sol.push_back(e[x].idx);
        }
    }
    cout << sol.size() << "\n";
    for(auto x : sol){
        cout << x << "\n";
    }
    return 0;
}