Cod sursa(job #2955865)

Utilizator andlftLefter Andrei andlft Data 17 decembrie 2022 23:28:11
Problema Cuplaj maxim in graf bipartit Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.53 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

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

class Graph
{
private:
//    long long maxFlow = 0;
    vector<int> parent;
    vector<bool> seen;
    vector<vector<int>> graph;
    vector<vector<int>> capacityFromXtoY;
    int noOfVerticesInFirstSet;
    int noOfVertices;
    int noOfEdges;
    int lastVertex;

public:
    Graph(int n, int n1, int m)
    {
        noOfVertices = n;
        noOfEdges = m;
        lastVertex = n;
        noOfVerticesInFirstSet = n1;
        graph.resize(n+1);
        capacityFromXtoY.resize(n+1);
        for (int i = 0; i <=n; i++)
        {
            capacityFromXtoY[i].resize(n+1, 0);
        }
        parent.resize(n+1, 0);
        seen.resize(n+1, 0);
    }

    void readEdges()
    {
        for(int i = 1; i <= noOfEdges; i++)
        {
            int x, y;
            fin >> x >> y;
            capacityFromXtoY[x][noOfVerticesInFirstSet+y] = 1;
            graph[x].push_back(noOfVerticesInFirstSet+y);
            graph[noOfVerticesInFirstSet+y].push_back(x);
        }
    }

    void addAdditionalEdges()
    {
        for(int i = 1; i <= noOfVerticesInFirstSet; i++)
        {
            capacityFromXtoY[0][i] = 1;
            graph[0].push_back(i);
            graph[i].push_back(0);
        }
        for(int i = noOfVerticesInFirstSet+1; i < noOfVertices; i++)
        {
            capacityFromXtoY[i][lastVertex] = 1;
            graph[i].push_back(lastVertex);
            graph[lastVertex].push_back(i);
        }
    }

    bool bfs()
    {
        seen.assign(noOfVertices + 2, 0);
        parent.assign(noOfVertices + 2, 0);
        queue<int> que;
        que.push(0);
        seen[0] = true;
        parent[0] = 0;
        while (!que.empty())
        {
            int front = que.front();
            que.pop();
            if(front != lastVertex)
            {
                for(auto nvertex = graph[front].begin(); nvertex != graph[front].end(); nvertex++)
                {
                    if(seen[*nvertex] == false && capacityFromXtoY[front][*nvertex] > 0)
                    {
                        que.push(*nvertex);
                        parent[*nvertex] = front;
                        seen[*nvertex] = true;
                    }
                }
            }
        }
        return seen[lastVertex];
    }

    void getMaxFlow()
    {
        while (this->bfs())
        {
            for(auto nvertex = graph[lastVertex].begin(); nvertex != graph[lastVertex].end(); nvertex++)
            {
                if(seen[*nvertex])
                {
                    parent[lastVertex] = *nvertex;
                    int localMaxFlow = 1<<30;
                    int vrtx = lastVertex;
                    while(vrtx != 0)
                    {
                        localMaxFlow = min(localMaxFlow, capacityFromXtoY[parent[vrtx]][vrtx]);
                        vrtx = parent[vrtx];
                    }
                    if(localMaxFlow == 0)
                    {
                        continue;
                    }
                    vrtx = lastVertex;
                    while(vrtx != 0)
                    {
                        capacityFromXtoY[parent[vrtx]][vrtx] -= localMaxFlow;
                        capacityFromXtoY[vrtx][parent[vrtx]] += localMaxFlow;
                        vrtx = parent[vrtx];
                    }
                   //maxFlow += localMaxFlow;


                }
            }
        }

//        return maxFlow;
    }

    void outputMatchings()
    {
        vector<int>ret1, ret2;
        int counter = 0;
        for (int i = 1; i < noOfVerticesInFirstSet; i++)
        {
            for (auto nvertex = graph[i].begin(); nvertex != graph[i].end(); nvertex++)
            {
                if(*nvertex != 0 && capacityFromXtoY[i][*nvertex] == 0)
                {
                    ret1.push_back(i);
                    ret2.push_back(*nvertex - noOfVerticesInFirstSet);
                    counter++;
                }
            }
        }
        fout<<counter<<"\n";
        for (int i = 0; i < counter; i++)
        {
            fout<<ret1[i]<<" "<<ret2[i]<<"\n";
        }
    }


};

int main()
{
    int n, m, s;
    fin>>n>>s>>m;
    Graph graph (n+s+1, n, m);
    graph.readEdges();
    graph.addAdditionalEdges();
    graph.getMaxFlow();
    graph.outputMatchings();
    return 0;
}