Cod sursa(job #2842264)

Utilizator vmnechitaNechita Vlad-Mihai vmnechita Data 31 ianuarie 2022 14:43:52
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 8.23 kb
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pf push_front
#define MOD 1000000007
#define MAX 1005

using namespace std;

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

vector < int > v[MAX];
pair < int, int > a[MAX][MAX];
int n, minn, r, prec[MAX], nvl[MAX];
bool gasit;

void nivelare(int nod);
void dfs(int nod);

int main()
{
    int m, i, x, y, z;

    fin >> n >> m;
    for(i = 1; i <= m; i++)
    {
        fin >> x >> y >> z;
        a[x][y].second = z;
        v[x].pb(y), v[y].pb(x);
    }

    nvl[n] = 1;
    while(nvl[n] != 0)
    {
        for(i = 1; i <= n; i++) nvl[i] = 0;
        nivelare(1);

        gasit = 1;
        while(gasit == 1)
        {
            minn = INT_MAX, gasit = 0, prec[1] = 0;
            dfs(1);
            if(gasit == 1) r += minn;
        }
    }

    fout << r;

    return 0;
}

void nivelare(int nod)
{
    queue < int > q;
    q.push(nod), nvl[nod] = 1;
    while(q.empty() == 0)
    {
        nod = q.front(), q.pop();
        for(auto it:v[nod]) if(a[nod][it].second - a[nod][it].first > 0 && nvl[it] == 0) nvl[it] = nvl[nod] + 1, q.push(it);
    }
}

void dfs(int nod)
{
    int i;

    for(auto it = begin(v[nod]); gasit == 0 && it != end(v[nod]); it++)
        if(a[nod][*it].second - a[nod][*it].first > 0 && nvl[*it] == nvl[nod] + 1)
        {
            prec[*it] = nod;

            if(*it != n) dfs(*it);
            else
            {
                gasit = 1, i = *it;
                while(prec[i] != 0) minn = min(minn, a[prec[i]][i].second - a[prec[i]][i].first), i = prec[i];
            }

            if(gasit == 1)
            {
                a[nod][*it].first += minn;
                a[*it][nod].first -= minn;
            }
        }
}

/// Edmonds-Karp algorithm with Capacity Scaling - Solutie de 70 de puncte (8 teste)
/*
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pf push_front
#define MOD 1000000007
#define MAX 1005

using namespace std;

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

vector < int > v[MAX];
pair < int, int > a[MAX][MAX];
int n, minn, r, prag, prec[MAX];
bool gasit, viz[MAX];

void bfs(int nod);

int main()
{
    int m, i, x, y, z, maxx = 0;

    fin >> n >> m;
    for(i = 1; i <= m; i++)
    {
        fin >> x >> y >> z;
        a[x][y].second = z, maxx = max(maxx, z);
        v[x].pb(y), v[y].pb(x);
    }

    prag = (1<<int(log2(maxx)));
    while(prag != 0)
    {
        for(i = 1; i <= n; i++) viz[i] = 0;
        minn = INT_MAX, gasit = 0, prec[1] = 0;
        bfs(1);
        if(gasit == 1) r += minn;
        else prag /= 2;
    }

    fout << r;

    return 0;
}

void bfs(int nod)
{
    int i;

    queue < int > q;
    q.push(nod), viz[nod] = 1;
    while(q.empty() == 0 && gasit == 0)
    {
        nod = q.front(), q.pop();
        for(auto it = begin(v[nod]); gasit == 0 && it != end(v[nod]); it++)
            if(a[nod][*it].second - a[nod][*it].first >= prag && viz[*it] == 0)
            {
                prec[*it] = nod;
                if(*it == n)
                {
                    gasit = 1, i = *it;
                    while(prec[i] != 0) minn = min(minn, a[prec[i]][i].second - a[prec[i]][i].first), i = prec[i];

                    i = *it;
                    while(prec[i] != 0) a[prec[i]][i].first += minn, a[i][prec[i]].first -= minn, i = prec[i];
                }
                else q.push(*it), viz[*it] = 1;
            }
    }
}
*/

/// Edmonds-Karp algorithm - Solutie de 70 de puncte (7 teste)
/*
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pf push_front
#define MOD 1000000007
#define MAX 1005

using namespace std;

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

vector < int > v[MAX];
pair < int, int > a[MAX][MAX];
int n, minn, r, prec[MAX];
bool gasit, viz[MAX];

void bfs(int nod);

int main()
{
    int m, i, x, y, z;

    fin >> n >> m;
    for(i = 1; i <= m; i++)
    {
        fin >> x >> y >> z;
        a[x][y].second = z;
        v[x].pb(y), v[y].pb(x);
    }

    gasit = 1;
    while(gasit == 1)
    {
        for(i = 1; i <= n; i++) viz[i] = 0;
        minn = INT_MAX, gasit = 0, prec[1] = 0;
        bfs(1);
        if(gasit == 1) r += minn;
    }

    fout << r;

    return 0;
}

void bfs(int nod)
{
    int i;

    queue < int > q;
    q.push(nod), viz[nod] = 1;
    while(q.empty() == 0 && gasit == 0)
    {
        nod = q.front(), q.pop();
        for(auto it = begin(v[nod]); gasit == 0 && it != end(v[nod]); it++)
            if(a[nod][*it].second - a[nod][*it].first > 0 && viz[*it] == 0)
            {
                prec[*it] = nod;
                if(*it == n)
                {
                    gasit = 1, i = *it;
                    while(prec[i] != 0) minn = min(minn, a[prec[i]][i].second - a[prec[i]][i].first), i = prec[i];

                    i = *it;
                    while(prec[i] != 0) a[prec[i]][i].first += minn, a[i][prec[i]].first -= minn, i = prec[i];
                }
                else q.push(*it), viz[*it] = 1;
            }
    }
}
*/

/// Ford-Fulkerson algorithm with Capacity Scaling - Solutie de 70 de puncte (9 teste)
/*
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pf push_front
#define MOD 1000000007
#define MAX 1005

using namespace std;

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

vector < int > v[MAX];
pair < int, int > a[MAX][MAX];
int n, minn, r, prag, prec[MAX];
bool gasit, viz[MAX];

void dfs(int nod);

int main()
{
    int m, i, x, y, z, maxx = 0;

    fin >> n >> m;
    for(i = 1; i <= m; i++)
    {
        fin >> x >> y >> z;
        a[x][y].second = z, maxx = max(maxx, z);
        v[x].pb(y), v[y].pb(x);
    }


    prag = (1<<int(log2(maxx)));
    while(prag != 0)
    {
        for(i = 1; i <= n; i++) viz[i] = 0;
        minn = INT_MAX, gasit = 0, prec[1] = 0;
        dfs(1);
        if(gasit == 1) r += minn;
        else prag /= 2;
    }

    fout << r;

    return 0;
}

void dfs(int nod)
{
    int i;

    viz[nod] = 1;
    for(auto it = begin(v[nod]); gasit == 0 && it != end(v[nod]); it++)
        if(a[nod][*it].second - a[nod][*it].first >= prag && viz[*it] == 0)
        {
            prec[*it] = nod;

            if(*it != n) dfs(*it);
            else
            {
                gasit = 1, i = *it;
                while(prec[i] != 0) minn = min(minn, a[prec[i]][i].second - a[prec[i]][i].first), i = prec[i];
            }

            if(gasit == 1)
            {
                a[nod][*it].first += minn;
                a[*it][nod].first -= minn;
            }
        }
}
*/

/// Ford-Fulkerson algorithm - Solutie de 70 de puncte (7 teste)
/*
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pf push_front
#define MOD 1000000007
#define MAX 1005

using namespace std;

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

vector < int > v[MAX];
pair < int, int > a[MAX][MAX];
int n, minn, r, prec[MAX];
bool gasit, viz[MAX];

void dfs(int nod);

int main()
{
    int m, i, x, y, z;

    fin >> n >> m;

    for(i = 1; i <= m; i++)
    {
        fin >> x >> y >> z;
        a[x][y].second = z;
        v[x].pb(y), v[y].pb(x);
    }

    gasit = 1;
    while(gasit == 1)
    {
        for(i = 1; i <= n; i++) viz[i] = 0;
        minn = INT_MAX, gasit = 0, prec[1] = 0;
        dfs(1);
        if(gasit == 1) r += minn;
    }

    fout << r;

    return 0;
}

void dfs(int nod)
{
    int i;

    viz[nod] = 1;
    for(auto it = begin(v[nod]); gasit == 0 && it != end(v[nod]); it++)
        if(a[nod][*it].second - a[nod][*it].first > 0 && viz[*it] == 0)
        {
            prec[*it] = nod;

            if(*it != n) dfs(*it);
            else
            {
                gasit = 1, i = *it;
                while(prec[i] != 0) minn = min(minn, a[prec[i]][i].second - a[prec[i]][i].first), i = prec[i];
            }

            if(gasit == 1)
            {
                a[nod][*it].first += minn;
                a[*it][nod].first -= minn;
            }
        }
}
*/