Pagini recente » Cod sursa (job #810568) | Cod sursa (job #2716018) | Cod sursa (job #38226) | Cod sursa (job #647434) | Cod sursa (job #2959446)
#include <bits/stdc++.h>
using namespace std;
int Nodes, Edges;
vector<int> *AdjacencyList, *InnerList;
// 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(int i = 0; i < AdList[Node].size(); i++){
int NodeNext = AdList[Node][i];
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(int i = 0; i < AdInList[Node].size(); i++){
int NodeNext = AdInList[Node][i];
if( visited[NodeNext] != 1 && flux[Node][NodeNext] > 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;
}
int FindMaxFlow(int Source, int Destination){
int source = Source, destination = Destination, dest, maxflow = 0;
int *dad = new int[Nodes + 1], *visited = new int [Nodes + 1];
// While we can discover unsaturated path
while(FindUnsaturatedPath(source, destination, Nodes, AdjacencyList, InnerList, 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;
}
return maxflow;
}
int main() {
int NodeX, NodeY;
long MaxFlow;
////////////////////////////
/////// READING DATA ///////
////////////////////////////
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
fin >> Nodes >> Edges;
// Resize adjacency lists
AdjacencyList = new vector<int>[Nodes+1];
InnerList = 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 >> MaxFlow;
AdjacencyList[NodeX].push_back(NodeY);
InnerList[NodeY].push_back(NodeX);
// Initialize matrixs
cost[NodeX][NodeY] = MaxFlow;
flux[NodeX][NodeY] = 0;
}
fout << FindMaxFlow(1, Nodes);
fin.close();
fout.close();
return 0;
}