Pagini recente » Cod sursa (job #979768) | Cod sursa (job #1732103) | Cod sursa (job #67675) | Cod sursa (job #1689487) | Cod sursa (job #2966901)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int s, n, e, source, sink, m;
vector<int> visited;
vector<int> parent;
vector<vector<int>> edges_pos;
struct edge
{
int x, y, capacity, pos;
};
vector<edge> edges;
//alg normal de bfs folosit la Edmonds Karp
int bfs(){
parent.clear();
parent.resize(s);
fill(visited.begin(), visited.end(), 0);
queue<int> q;
q.push(source);
visited[source] = 1;
while(!q.empty()){
int nod = q.front();
q.pop();
if(nod == sink)
continue;
for(int i : edges_pos[nod]){
edge m_curent = edges[i];
if(!visited[m_curent.y] and m_curent.capacity != 0)
{
visited[m_curent.y] = 1;
parent[m_curent.y] = i;
q.push(m_curent.y);
}
}
}
return visited[sink];
}
//alg lui Edmonds Karp
int flux_Maxim(){
int max_flow = 0;
while(bfs()){
for(auto i:edges_pos[sink]){
if(visited[edges[i].y] and edges[edges[i].pos].capacity != 0)
{
int min_flow = INT_MAX;
edge m_curent = edges[i];
parent[sink] = m_curent.pos;
int nod = sink;
while(nod != source){
min_flow = min(min_flow, edges[parent[nod]].capacity);
nod = edges[parent[nod]].x;
}
nod = sink;
while(nod != source){
edges[parent[nod]].capacity -= min_flow;
edges[edges[parent[nod]].pos].capacity += min_flow;
nod = edges[parent[nod]].x;
}
max_flow += min_flow;
}
}
}
return max_flow;
}
int main() {
f>>n>>m>>e;
//la graful nostru vom adauga doua noduri noi: source si sink
//(exact cum aveam la problema de max flow)
s = n + m + 2;//nr nou de noduri va creste cu 2
//source va fi primul nod
source = 0;
//sink va fi ultimul nod
sink = s - 1;
visited.resize(s);
parent.resize(s);
edges_pos.resize(s);
//Modificarile aduse alg lui Edmonds Karp:
//legam nodul sursa de toate noduri din multimea L
//legam toate nodurile din multimea L cu nodurile din multimea R
//legam toate nodurile din multimea R cu nodul final
//de asemenea, alegem capacitatea fiecarei muchii ca fiind 1, pentru a face matching 1 la 1
for(int i = 1; i <= e; i++){
int x, y;
f>>x>>y;
edges.push_back({x, y + n, 1, 2 * i - 1});
edges.push_back({y + n, x, 0, 2 * i - 2});
edges_pos[y + n].push_back(2 * i - 1);
edges_pos[x].push_back(2 * i - 2);
}
int dimensiune_muchii = int (edges.size());
for(int i = 1; i <= n; i++){
dimensiune_muchii += 2;
edges.push_back({source, i, 1, dimensiune_muchii - 1});
edges.push_back({i, source, 0, dimensiune_muchii - 2});
edges_pos[i].push_back(dimensiune_muchii - 1);
edges_pos[source].push_back(dimensiune_muchii - 2);
}
for(int i = n + 1; i < s - 1; i++){
dimensiune_muchii += 2;
edges.push_back({i, sink, 1, dimensiune_muchii - 1});
edges.push_back({sink, i, 0, dimensiune_muchii - 2});
edges_pos[sink].push_back(dimensiune_muchii - 1);
edges_pos[i].push_back(dimensiune_muchii - 2);
}
//apelam functia care ne va da fluxul maxim
g<<flux_Maxim()<<"\n";
for(auto & i : edges){
//afisam muchiile pe care am facut matching
if(i.capacity == 0 and i.x != source and i.y != sink and i.x < i.y){
g<<i.x<<" "<<i.y - n<<"\n";
}
}
return 0;
}