Cod sursa(job #2474494)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 15 octombrie 2019 12:27:09
Problema Critice Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.41 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const int N = 1000 + 7;
int n, m;
vector <int> g[N];
int cap[N][N], level[N];
int wtf[N][N];
int id[N][N];
bool good[N][N];

void build()
{
        for (int i = 1; i <= n; i++)
                level[i] = -1;
        level[1] = 0;
        queue <int> q;
        q.push(1);

        while (!q.empty())
        {
                int a = q.front();
                q.pop();
                for (auto &b : g[a])
                        if (level[b] == -1)
                        {
                                level[b] = 1 + level[a];
                                q.push(b);
                        }
        }

        for (int a = 1; a <= n; a++)
                for (auto &b : g[a])
                        if (level[a] < level[b])
                        {
                                cap[a][b] = wtf[a][b];
                                good[a][b] = 1;
                        }

        for (int a = 1; a <= n; a++)
                for (auto &b : g[a])
                        if (level[a] == level[b] && a < b)
                        {
                                cap[a][b] = wtf[a][b];
                                good[a][b] = 1;
                        }
}

bool u[N];
int par[N];
bool pump_flow()
{
        for (int i = 1; i <= n; i++)
                u[i] = 0;
        u[1] = 1;
        queue <int> q;
        q.push(1);

        while (!q.empty())
        {
                int a = q.front();
                q.pop();
                for (auto &b : g[a])
                        if (u[b] == 0 && cap[a][b])
                        {
                                par[b] = a;
                                u[b] = 1;
                                q.push(b);
                        }
        }

        return u[n];
}

int get_flow()
{
        int flow = 0;
        while (pump_flow())
                for (auto &go : g[n])
                        if (cap[go][n])
                        {
                                int mn = cap[go][n], cur = go;
                                while (cur != 1)
                                {
                                        int p = par[cur];
                                        mn = min(mn, cap[p][cur]);
                                        cur = p;
                                }
                                if (mn)
                                {
                                        flow += mn;
                                        cap[go][n] -= mn;
                                        cur = go;
                                        while (cur != 1)
                                        {
                                                int p = par[cur];
                                                cap[p][cur] -= mn;
                                                cap[cur][p] += mn;
                                                cur = p;
                                        }
                                }
                        }
        return flow;
}

bool fi[N];
bool sc[N];

void send_fi(int a)
{
        fi[a] = 1;
        for (auto &b : g[a])
                if (fi[b] == 0 && cap[a][b])
                        send_fi(b);
}

bool send_sc(int a)
{
        sc[a] = 1;
        for (auto &b : g[a])
                if (sc[b] == 0 && cap[b][a])
                        send_sc(b);
}

int main()
{
        freopen ("critice.in", "r", stdin);
        freopen ("critice.out", "w", stdout);

        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++)
        {
                int x, y, c;
                scanf("%d%d%d", &x, &y, &c);
                wtf[x][y] = wtf[y][x] = c;
                id[x][y] = id[y][x] = i;
                g[x].push_back(y);
                g[y].push_back(x);
        }

        build();
        int flow = get_flow();
        send_fi(1);
        send_sc(n);
        vector <int> sol;

        for (int i = 1; i <= n; i++)
                for (auto j : g[i])
                        if (good[i][j] && cap[i][j] == 0 && fi[i] && sc[j])
                                sol.push_back(id[i][j]);

        sort(sol.begin(), sol.end());
        cout << (int) sol.size() << "\n";
        for (auto &i : sol)
                cout << i << "\n";

        return 0;
}