Cod sursa(job #2962181)

Utilizator Eronatedudu zzz Eronate Data 7 ianuarie 2023 22:01:03
Problema Cuplaj maxim in graf bipartit Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.45 kb
#include <bits/stdc++.h>

using namespace std;

unordered_map<int,int> bp[20001];

int n,m,e;

ifstream f("cuplaj.in");
ofstream g("cuplaj.out");

int father[20001], visited[20001];

//bool bfs(int n, int src, int dest)
//{
//    for(int i=1; i<dest; i++)
//    {
//        father[i] = -1;
//        visited[i] = 0;
//    }
//    visited[dest] = 0;
//    queue<int> vertexes;
//    vertexes.push(src);
//
//    while(!vertexes.empty())
//    {
//        int currentNode = vertexes.front();
//        vertexes.pop();
//        for(auto pairKeyFlow: bp[currentNode])
//        {
//                if(!visited[pairKeyFlow.first] and pairKeyFlow.second>0)
//                {
//                   // cout<<currentNode<<' '<<pairKeyFlow.first<<' '<<pairKeyFlow.second<<'\n';
//                    father[pairKeyFlow.first] = currentNode;
//                    if(pairKeyFlow.first == dest)
//                        return true;
//                    vertexes.push(pairKeyFlow.first);
//                    visited[pairKeyFlow.first] = 1;
//                }
//        }
//
//    }
//    return false; //nu am gasit un drum de la sursa la destinatie, inseamna nu mai am drumuri si ca am ajuns la flux maxim
//}

//dfs
bool dfs(int n, int src, int dest)
{
    for(int i=1; i<dest; i++)
    {
        father[i] = -1;
        visited[i] = 0;
    }
    visited[dest] = 0;
    stack<int> vertexes;
    vertexes.push(src);

    while(!vertexes.empty())
    {
        int currentNode = vertexes.top();
        vertexes.pop();
        for(auto pairKeyFlow: bp[currentNode])
        {
            if(!visited[pairKeyFlow.first] and pairKeyFlow.second>0)
            {
                // cout<<currentNode<<' '<<pairKeyFlow.first<<' '<<pairKeyFlow.second<<'\n';
                father[pairKeyFlow.first] = currentNode;
                if(pairKeyFlow.first == dest)
                    return true;
                vertexes.push(pairKeyFlow.first);
                visited[pairKeyFlow.first] = 1;
            }
        }

    }
    return false; //nu am gasit un drum de la sursa la destinatie, inseamna nu mai am drumuri si ca am ajuns la flux maxim
}


int fordFulkerson(int n, int src, int dest)
{
    int u, v, max_flow_for_route, currentNode;

    int srcAux = src, destAux = dest, fNode, finalFlow = 0;

    while(dfs(n, src, dest))
    {

        srcAux = src;
        destAux = dest;

        while(destAux!=srcAux)
        {
            fNode = father[destAux];
            bp[fNode][destAux] -= 1;    //muchia mea pe directia corecta va avea o capacitate mai mica de flow
            bp[destAux][fNode] += 1;    //muchia pe directia inversa va avea mai mult flow de dat
            //logic pt ca voi avea mai mult flow de extras
            destAux = fNode;
        }

        finalFlow += 1; //adun flow-ul drumului la flow-ul final
    }
    return finalFlow;
}

int main()
{
    f>>n>>m>>e;
    int node1,node2;
    int delay=n, destination = n+m+1, source = 0;
    for(int i=1;i<=e;i++)
    {
        f>>node1>>node2;
        bp[node1][node2+delay] = 1;
        bp[node2+delay][node1] = 0;
    }
    for(int i=1;i<=n;i++)
        bp[source][i] = 1;
    for(int i=n+1;i<destination;i++)
        bp[i][destination] =1;
    g<<fordFulkerson(n,source,destination)<<'\n';
    for(int i=1;i<=n;i++)
        for(auto j : bp[i])
            if(bp[i][j.first] == 0)
                g<<i<<' '<<j.first - delay<<'\n';


}