Cod sursa(job #1809872)

Utilizator CiurezAndreiCiurez Marius-Andrei CiurezAndrei Data 19 noiembrie 2016 13:11:40
Problema Critice Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.67 kb
#include <bits/stdc++.h>

#define source 1
#define destination N
#define INF 100000000

using namespace std;

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

int N, M;
int capacity[1024][1024], flow[1024][1024], T[1024];
vector<int> L[1024], solution;
queue <int> Q;
bitset<1024>viz, viz2;
vector<pair<int, int> > ans;

struct pair_hash
{
    template <class T1, class T2>
    std::size_t operator () (const std::pair<T1, T2> &p) const {

        return p.first >= p.second ? p.first * p.first + p.first + p.second : p.first + p.second * p.second;
    }
};
unordered_map<pair<int, int>, int, pair_hash> H;

inline bool BFS()
{
    viz.reset();
    Q.push(source);

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

        for(int i = 0; i < L[node].size(); i ++)
        {
            int neighbour = L[node][i];
            if(viz[neighbour] == 0 && capacity[node][neighbour] > flow[node][neighbour])
            {
                Q.push(neighbour);
                T[neighbour] = node;
                viz[neighbour] = 1;
            }

        }
    }
    return viz[destination] == 1;
}

void DFS1(const int &node)
{
    viz[node] = 1;

    for(int i = 0; i < L[node].size(); i ++)
    {
        if(viz[ L[node][i] ] == 0 && capacity[node][ L[node][i] ] > flow[node][ L[node][i] ] )
        {
            DFS1(L[node][i]);
        }
    }
}

void DFS2(const int &node)
{
    viz2[node] = 1;

    for(int i = 0; i < L[node].size(); i ++)
    {
        int xx = L[node][i];
        if(viz[ L[node][i] ] == 0 && viz2[ L[node][i] ] == 0 && capacity[ L[node][i] ][ node ] > flow[ L[node][i] ][ node ] )
        {
            DFS2(L[node][i]);
        }
        else
        {
            if(viz2[ L[node][i] ] == 0 && capacity[ L[node][i] ][ node ] == flow[ L[node][i] ][ node ])
            {
                int primu = min(L[node][i], node);
                int doilea = max(L[node][i], node);
                ans.push_back(make_pair(L[node][i], node));
            }
        }
    }
}

int main()
{
    fin >> N >> M;
    for(int i = 1; i <= M; i ++)
    {
        int a, b, c;
        fin >> a >> b >> c;
        if(a > b)
        {
            swap(a, b);
        }
        H[ make_pair(a, b) ] = i;
        capacity[ a ][ b ] = c;
        capacity[ b ][ a ] = c;
        L[ a ].push_back(b);
        L[ b ].push_back(a);
    }

    while(BFS())
    {
        int Fmin = INF;

        for(int i = 0; i < L[destination].size(); i ++)
        {
            int x = L[destination][i];

            if(capacity[x][destination] > flow[x][destination] && viz[x] == 1)
            {
                Fmin = capacity[x][destination] - flow[x][destination];
                while(x > source)
                {
                    Fmin = min(Fmin, capacity[ T[x] ][x] - flow[ T[x] ][x]);
                    x = T[x];
                }

                x = L[destination][i];
                flow[x][destination] += Fmin;
                flow[destination][x] -= Fmin;

                while(x > source)
                {
                    flow[ T[x] ][x] += Fmin;
                    flow[x][ T[x] ] -= Fmin;
                    x = T[x];
                }
            }
        }
    }

    viz.reset();
    DFS1(source);
    DFS2(destination);

    fout << ans.size() << '\n';
    for(int i = 0; i < ans.size(); i ++)
    {
        pair<int, int> cheie = ans[i];
        solution.push_back(H[ cheie ]);
    }

    sort(solution.begin(), solution.end());
    for(int i = 0; i < solution.size(); i ++)
    {
        fout << solution[i] << '\n';
    }

    return 0;
}