Cod sursa(job #2709647)

Utilizator PopescuAndreiAlexandruPopescu Andrei Alexandru PopescuAndreiAlexandru Data 20 februarie 2021 20:32:30
Problema Critice Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.42 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 M = 10005;
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;

struct Tuple
{
    int x, y, z;
};

vector<Tuple> 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({x, y, c});
        }
    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 Print()
{
    int countEdges = 0;
    for (int i = 0; i < m; i++)
        {
            memset(Flow, 0, sizeof(Flow));
            Cap[P[i].x][P[i].y]++;
            Cap[P[i].y][P[i].x]++;
            FindFlow(NewMaxFlow);
            if (NewMaxFlow > MaxFlow)
                {
                    countEdges++;
                    Check[i] = 1;
                }
            Cap[P[i].x][P[i].y]--;
            Cap[P[i].y][P[i].x]--;
        }
    fout << countEdges << '\n';
    for (int i = 0; i < m; i++)
        {
            if (Check[i])
                fout << i + 1 << '\n';
        }
}

int main()
{
    Read();
    FindFlow(MaxFlow);
    Print();
}