Cod sursa(job #2709801)

Utilizator PopescuAndreiAlexandruPopescu Andrei Alexandru PopescuAndreiAlexandru Data 21 februarie 2021 12:22:57
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.14 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
#include <queue>
#include <stack>

using namespace std;

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

const int N = 1005;

int n, m, x, y, c, source, sink, Cap[N][N], Flow[N][N], t[N], seen[N], Check[N], MaxFlow = 0, NewMaxFlow, Dsource[N], Dsink[N], countEdges;

vector<pair<int, int> > P;
vector<int> G[N];

void Read()
{
    fin >> n >> m;
    for (int i = 1; i <= m; i++)
        {
            fin >> x >> y >> c;
            Cap[x][y] = Cap[y][x] = c;
            G[x].push_back(y);
            G[y].push_back(x);
            P.push_back(make_pair(x, y));
        }
    source = 1;
    sink = n;
}

bool BFS(int source, int sink)
{
    queue<int> Q;
    memset(seen, 0, sizeof(seen));
    memset(t, 0, sizeof(t));
    Q.push(source);
    seen[source] = 1;
    while (!Q.empty())
        {
            int nod = Q.front();
            Q.pop();
            vector<int>::iterator it;
            for (it = G[nod].begin(); it != G[nod].end(); it++)
                {
                    int next = (*it);
                    if (!seen[next] && Cap[nod][next] - Flow[nod][next] > 0)
                        {
                            seen[next] = 1;
                            t[next] = nod;
                            Q.push(next);
                        }
                }
        }
    if (!t[sink])
        return false;
    return true;
}

void FindFlow(int &MaxFlow)
{
    MaxFlow = 0;
    while (BFS(source, sink))
        {
            vector<int>::iterator it;
            for (it = G[sink].begin(); it != G[sink].end(); it++)
                {
                    int next = (*it);
                    if (Cap[next][sink] - Flow[next][sink] > 0 && seen[next])
                        {
                            int Min = Cap[next][sink] - Flow[next][sink];
                            int p = next;
                            while (t[p])
                                {
                                    Min = min(Min, Cap[t[p]][p] - Flow[t[p]][p]);
                                    p = t[p];
                                }
                            p = next;
                            Flow[next][sink] += Min;
                            Flow[sink][next] -= Min;
                            while (t[p])
                                {
                                    Flow[t[p]][p] += Min;
                                    Flow[p][t[p]] -= Min;
                                    p = t[p];
                                }
                            MaxFlow += Min;
                        }
                }
        }
}

void BFS_RG(int start, int Dist[])
{
    queue<int> Q;
    Q.push(start);
    Dist[start] = 1;
    while (!Q.empty())
        {
            int nod = Q.front();
            Q.pop();
            vector<int>::iterator it;
            for (it = G[nod].begin(); it != G[nod].end(); it++)
                {
                    int next = (*it);
                    if (!Dist[next] && Cap[nod][next] - abs(Flow[nod][next]) > 0)
                        {
                            Dist[next] = Dist[nod] + 1;
                            Q.push(next);
                        }
                }
        }
}

void CriticalEdges()
{
    countEdges = 0;
    for (int i = 0; i < P.size(); i++)
        {
            int a = P[i].first;
            int b = P[i].second;
            if (!(Cap[a][b] - abs(Flow[a][b])))
                {
                    if ((Dsource[a] && Dsink[b]) || (Dsource[b] && Dsink[a]))
                        {
                            countEdges++;
                            Check[i] = 1;
                        }
                }
        }
}

void Print()
{
    fout << countEdges << '\n';
    for (int i = 0; i < P.size(); i++)
        {
            if (Check[i])
                fout << i + 1 << '\n';
        }
}

int main()
{
    Read();
    FindFlow(MaxFlow);
    BFS_RG(source, Dsource);
    BFS_RG(sink, Dsink);
    CriticalEdges();
    Print();
}