Cod sursa(job #2986932)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 1 martie 2023 17:17:54
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.36 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;

ifstream fin("critice.in");
ofstream fout("critice.out");

const int INF = 0x3f3f3f3f;
const int MAX_N = 1005;
const int MAX_M = 10005;

struct Edge {
    int a, b;

    inline bool operator == (const Edge& other) {
        if ((a == other.a && b == other.b) || (b == other.a && a == other.b)) {
            return true;
        }
        return false;
    }
 };

int n, m;
int graph[MAX_N][MAX_N];
int flow[MAX_N][MAX_N];
int saturated[MAX_N][MAX_N];
bool visited[MAX_N];
int father[MAX_N];
Edge inputEdges[MAX_M];
vector <int> BFSGraph[MAX_N];
queue <int> BFSQueue;
vector <int> criticalEdges;


void InitBFSQueue() {
    while (!BFSQueue.empty()) {
        BFSQueue.pop();
    }
    BFSQueue.push(1);
}

bool BFS() {
    InitBFSQueue();

    memset(father, 0, sizeof(father));
    father[1] = 1;

    while (!BFSQueue.empty()) {
        int node = BFSQueue.front();
        BFSQueue.pop();

        if (node == n) {
            return true;
        }

        for (int newNode : BFSGraph[node]) {
            if (!father[newNode] && graph[node][newNode] - flow[node][newNode] > 0) {
                BFSQueue.push(newNode);
                father[newNode] = node;
            }
        }
    }
    return false;
}

int GetMinCapacity() {
    int node = n;
    int minCapacity = INF;

    while (father[node] != node) {
        int parent = father[node];

        if (graph[parent][node] - flow[parent][node] < minCapacity) {
            minCapacity = graph[parent][node] - flow[parent][node];
        }
        node = parent;
    } 

    return minCapacity;
}

void UpdateFlow(int value) {
    int node = n;
    while (father[node] != node) {
        int parent = father[node];
        flow[parent][node] += value;
        flow[node][parent] -= value;
        node = parent;
    }
}

void DFS(int node) {
    visited[node] = true;

    for (int newNode : BFSGraph[node]) {
        if (visited[newNode]) {
            continue;
        }

        if (graph[node][newNode] == flow[node][newNode] || graph[newNode][node] == flow[newNode][node]) {
            saturated[node][newNode]++;
            saturated[newNode][node]++;
        }
        else {
            DFS(newNode);
        }
    }
}

void BuildSaturated() {
    memset(visited, false, sizeof(visited));
    DFS(1);

    memset(visited, false, sizeof(visited));
    DFS(n);
}

void BuildAnswer() {
    for (int i = 1; i <= m; i++) {
        Edge inputEdge = inputEdges[i];
        if (saturated[inputEdge.a][inputEdge.b] == 2) {
            criticalEdges.push_back(i);
        }
    }

    fout << criticalEdges.size() << '\n';
    for (int edgeIdx : criticalEdges) {
        fout << edgeIdx << '\n';
    }
}


int main() {
    fin >> n >> m;

    for (int i = 1; i <= m; i++) {
        int a, b, c;
        fin >> a >> b >> c;

        graph[a][b] = c;
        graph[b][a] = c;

        BFSGraph[a].push_back(b);
        BFSGraph[b].push_back(a);

        Edge inputEdge = {a, b};
        inputEdges[i] = inputEdge;
    }

    while (BFS()) {
        int minCapacity = GetMinCapacity();
        UpdateFlow(minCapacity);
    }

    BuildSaturated();
    BuildAnswer();

    return 0;
}