Pagini recente » Cod sursa (job #825715) | Cod sursa (job #2388778) | Cod sursa (job #357000) | Cod sursa (job #2978775) | Cod sursa (job #2955865)
#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;
}