Pagini recente » Cod sursa (job #1945189) | Cod sursa (job #1788760) | Cod sursa (job #1325560) | Cod sursa (job #1240094) | Cod sursa (job #2959470)
#include <bits/stdc++.h>
using namespace std;
int Nodes, NodesL, NodesR, Edges;
vector<int> *AdjacencyList, *AdjacencyInnerList;
// Cost matrix, flux matrix
long **flux, **cost;
bool FindUnsaturatedPath(int Source, int Destination, int Nodess, vector<int> *AdList, vector <int> *AdInList, long **flux, long **cost, int *dad, int *visited){
queue <int> Q;
int Node;
for(int i = 0; i <= Nodess; i++){
visited[i] = dad[i] = 0;
}
// Add the source in the queue
Q.push(Source);
// Mark the starting node as visited
visited[Source] = 1;
while(!Q.empty()){
Node = Q.front();
Q.pop();
// For the edges leaving from Node,
// check if it can be added more flux
for(auto NodeNext : AdList[Node]){
if( visited[NodeNext] != 1 && flux[Node][NodeNext] != cost[Node][NodeNext]){
dad[NodeNext] = Node;
// Check if the path reached the destination, and if it did
// exit the function
if(NodeNext == Destination)
return true;
Q.push(NodeNext);
visited[NodeNext] = 1;
}
}
// For the edges coming into Node,
// check if it can be added more flux
for(auto NodeNext : AdInList[Node]){
if( visited[NodeNext] != 1 && flux[NodeNext][Node] > 0){
dad[NodeNext] = -Node;
// Check if the path reached the destination, and if it did
// exit the function
if(NodeNext == Destination)
return true;
Q.push(NodeNext);
visited[NodeNext] = 1;
}
}
}
return false;
}
// Considering the left and the right set, two extra nodes will be added:
// -> source - has outer nodes to all nodes from the left set
// -> destination - all nodes from the right set will go into this new node
// EdmondsKarp starting from the source node, where each edge has the maximum capacity of 1
int main() {
int NodeX, NodeY;
////////////////////////////
/////// READING DATA ///////
////////////////////////////
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
fin >> NodesL >> NodesR >> Edges;
// + 2 --> for the pseudo nodes: starting and ending
Nodes = NodesL + NodesR + 2;
// Resize adjacency lists
AdjacencyList = new vector<int>[Nodes + 1];
AdjacencyInnerList = new vector<int>[Nodes + 1];
// Resize matrixs
flux = new long* [Nodes + 1];
cost = new long* [Nodes + 1];
for(int i = 0; i <= Nodes; i++){
flux[i] = new long [Nodes + 1];
cost[i] = new long [Nodes + 1];
}
for(int i = 0; i < Edges; i++){
fin >> NodeX >> NodeY;
// In the problem, we need to transform the Node 1 from the right
// set into 1 + NodesL, because we need to have a total of NodesR + NodesL nodes
AdjacencyList[NodeX].push_back(NodeY + NodesL);
AdjacencyInnerList[NodeY + NodesL].push_back(NodeX);
// Initialize matrixs
cost[NodeX][NodeY + NodesL] = 1;
flux[NodeX][NodeY + NodesL] = 0;
}
fin.close();
int source = Nodes - 1, destination = Nodes, dest, maxflow = 0;
int *dad = new int[Nodes + 1], *visited = new int [Nodes + 1];
// We add the nodes that leave the pseudo starting node
// ---> they will go into the nodes from the left set
for(int i = 1; i <= NodesL; i++){
AdjacencyList[source].push_back(i);
AdjacencyInnerList[i].push_back(source);
// Initialize matrixs
cost[source][i] = 1;
flux[source][i] = 0;
}
// We add the nodes that go into the pseudo ending node
// ---> they will come from the right set
for(int i = NodesL + 1; i <= NodesL + NodesR; i++){
AdjacencyList[i].push_back(destination);
AdjacencyInnerList[destination].push_back(i);
// Initialize matrixs
cost[i][destination] = 1;
flux[i][destination] = 0;
}
// While we can discover unsaturated path
while(FindUnsaturatedPath(source, destination, Nodes, AdjacencyList, AdjacencyInnerList, flux, cost, dad, visited)){
// Calculate the minimum rezidual capacity in the path that the
// function has found
long MRC = LONG_MAX;
dest = destination;
while(dest != source){
// Edge leaving from dad
if(dad[dest] >= 0){
if( cost[dad[dest]][dest] - flux[dad[dest]][dest] < MRC)
MRC = cost[dad[dest]][dest] - flux[dad[dest]][dest];
dest = dad[dest];
} else{
// Edge coming into dad
if( flux[dest][-dad[dest]] < MRC)
MRC = flux[dest][-dad[dest]];
dest = -dad[dest];
}
}
dest = destination;
while(dest != source){
if(dad[dest] > 0){
flux[dad[dest]][dest] += MRC;
dest = dad[dest];
} else{
flux[dest][-dad[dest]] -= MRC;
dest = -dad[dest];
}
}
maxflow += MRC;
}
fout << maxflow << endl;
for(int i = 1; i <= NodesL; i++){
for(int j = 0; j < AdjacencyList[i].size(); j++){
if(flux[i][AdjacencyList[i][j]] == 1){
fout << i << " " << int(AdjacencyList[i][j] % NodesL) << endl;
}
}
}
fout.close();
return 0;
}