Pagini recente » Cod sursa (job #481746) | Cod sursa (job #1143331) | Cod sursa (job #2676963) | Cod sursa (job #2656738) | Cod sursa (job #2208849)
#include <fstream>
#include <vector>
#include <list>
#include <queue>
#define INF 0x7fffffff
using namespace std;
struct graph {
int vertexCount;
int edgeCount;
list<int>* adjList;
list<int> setU;
list<int> setV;
int* dist;
int* matchOfU;
int* matchOfV;
};
void separateBiparts(graph& g) {
int* viz = new int[g.vertexCount + 1];
//memset(viz, false, g.vertexCount + 1);
int* part = new int[g.vertexCount + 1];
//memset(part, 0, g.vertexCount + 1);
for (int i = 0; i <= g.vertexCount; i++) {
viz[i] = false;
part[i] = 0;
}
queue<int> q;
q.push(1);
part[1] = 1;
g.setU.push_back(1);
while (!q.empty()) {
int crt = q.front();
q.pop();
viz[crt] = true;
for (auto elem : g.adjList[crt]) {
if (!viz[elem]) {
viz[elem] = true;
q.push(elem);
part[elem] = part[crt] == 1 ? 2 : 1;
if (part[elem] == 1)
g.setU.push_back(elem);
else
g.setV.push_back(elem);
}
}
}
delete part;
delete viz;
}
void readGraph(graph& g, ifstream& in) {
int a, b;
in >> a >> b >> g.edgeCount;
g.vertexCount = a + b;
g.adjList = new list<int>[g.vertexCount + 1];
for (int i = 1; i <= g.edgeCount; i++) {
int v1, v2;
in >> v1 >> v2;
v2 += a;
g.adjList[v1].push_back(v2);
g.adjList[v2].push_back(v1);
}
separateBiparts(g);
for (auto i : g.setU) {
g.adjList[0].push_back(i);
}
g.dist = new int[g.vertexCount + 1];
g.matchOfU = new int[g.vertexCount + 1];
g.matchOfV = new int[g.vertexCount + 1];
return;
}
bool bfs(graph& g) {
queue<int> bfsQ;
for (auto vertex : g.setU) {
if (g.matchOfU[vertex] == 0) {
g.dist[vertex] = 0;
bfsQ.push(vertex);
}
else
g.dist[vertex] = INF;
}
g.dist[0] = INF;
while (!bfsQ.empty()) {
int crtVert = bfsQ.front();
bfsQ.pop();
if(g.dist[crtVert] < g.dist[0])
for (auto vertex : g.adjList[crtVert]) {
if (g.dist[g.matchOfV[vertex]] == INF) {
g.dist[g.matchOfV[vertex]] = g.dist[crtVert] + 1;
bfsQ.push(g.matchOfV[vertex]);
}
}
}
return g.dist[0] != INF;
}
bool dfs(graph& g, int vertex) {
if (vertex != 0) {
for (auto adjVert : g.adjList[vertex]) {
if (g.dist[g.matchOfV[adjVert]] == (g.dist[vertex] + 1)) {
if (dfs(g, g.matchOfV[adjVert])) {
g.matchOfV[adjVert] = vertex;
g.matchOfU[vertex] = adjVert;
return true;
}
}
}
g.dist[vertex] = INF;
return false;
}
return true;
}
int hopcroftKarp(graph& g) {
for (int elem = 0; elem <= g.vertexCount; elem++) {
g.matchOfU[elem] = 0;
}
for (int elem = 0; elem <= g.vertexCount; elem++) {
g.matchOfV[elem] = 0;
}
int matchings = 0;
while (bfs(g)) {
for (auto vertex : g.setU) {
if (g.matchOfU[vertex] == 0 && dfs(g, vertex))
matchings++;
}
}
return matchings;
}
int main() {
graph g;
ifstream in("cuplaj.in");
readGraph(g, in);
in.close();
int matchings = hopcroftKarp(g);
ofstream out("cuplaj.out");
out << matchings << "\n";
for (auto elem : g.setU) {
if (g.matchOfU[elem] != 0)
out << elem << " " << g.matchOfU[elem]- g.setU.size() << "\n";
}
out.close();
return 0;
}