Pagini recente » Cod sursa (job #1628162) | Cod sursa (job #162825) | Cod sursa (job #878518) | Cod sursa (job #2797978) | Cod sursa (job #2693195)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
std::ifstream fin("fmcm.in");
std::ofstream fout("fmcm.out");
class Graph{
private:
int V, source, sink;
std::vector <std::vector <int>> edge;
std::vector <std::vector <int>> cap;
std::vector <std::vector <int>> cost;
std::vector <int> dist;
std::vector <int> parent, bellman;
std::vector <bool> visited;
void addAuxNode(){
for(int node=1; node<=V; node++)
edge[V+1].push_back(node),
cap[V+1][node] = 1,
cost[V+1][node] = 0;
}
void recreateGraph(){
for(int node=1; node<=V; node++){
for(int& next: edge[node])
cost[node][next] = cost[node][next] + bellman[node] - bellman[next];
}
}
void printGraph(){
for(int node=1; node<=V; node++){
for(int& next: edge[node])
fout << node << ' ' << next << ' ' << cap[node][next] << ' ' << cost[node][next] << '\n';
fout << '\n';
}
}
bool bfs(){
std::queue <int> q;
std::fill(visited.begin(), visited.end(), false);
visited[source] = true;
q.push(source);
while(q.empty() == false){
int node = q.front();
q.pop();
if(node == sink) continue;
for(auto& next: edge[node]){
if(visited[next] == false and cap[node][next] > 0){
visited[next] = true;
q.push(next);
parent[next] = node;
}
}
}
return visited[sink];
}
bool dijkstra(int src, int dest){
std::priority_queue <std::pair <int, int>, std::vector <std::pair <int, int>>, std::greater <std::pair <int, int>>> pq;
std::fill(visited.begin(), visited.end(), false);
std::fill(dist.begin(), dist.end(), 1e8);
dist[src] = 0;
visited[src] = true;
pq.push({0, src});
while(pq.empty() == false){
int node = pq.top().second;
int c = pq.top().first;
pq.pop();
if(dist[node] < c) continue;
if(node == dest) continue;
for(int& next: edge[node]){
if(dist[next] > dist[node] + cost[node][next] and cap[node][next] > 0){
dist[next] = dist[node] + cost[node][next];
pq.push({dist[next], next});
visited[next] = true;
parent[next] = node;
}
}
}
return visited[dest];
}
public:
Graph(int size){
V = size;
edge.resize(V+2);
cap.resize(V+2);
for(auto& line: cap)
line.resize(V+2);
cost.resize(V+2);
for(auto& line: cost)
line.resize(V+2);
}
void addEdge(int src, int dest, int capacity, int weight){
edge[src].push_back(dest);
edge[dest].push_back(src);
cap[src][dest] = capacity;
cost[src][dest] = weight;
cost[dest][src] = -weight;
}
int maxFlow(int src, int dest){
source = src;
sink = dest;
parent.resize(V+2);
visited.resize(V+2);
int maxFlow = 0, flow;
while(bfs() == true){
for(int& node: edge[sink]){
if(visited[node] == true and cap[node][sink] > 0){
parent[sink] = node;
flow = 1e9;
for(int curr = sink; curr != source; curr = parent[curr])
flow = std::min(flow, cap[parent[curr]][curr]);
for(int curr = sink; curr != source; curr = parent[curr]){
cap[parent[curr]][curr] -= flow;
cap[curr][parent[curr]] += flow;
}
maxFlow += flow;
}
}
}
return maxFlow;
}
void bellmanFord(int src){
bellman.resize(V+2);
std::fill(bellman.begin(), bellman.end(), 1e8);
bellman[src] = 0;
for(int count=1; count<V; count++){
for(int node=1; node<=V+1; node++)
for(int& next: edge[node])
if(cap[node][next] > 0)
bellman[next] = std::min(bellman[next], bellman[node] + cost[node][next]);
}
// for(int node=1; node<=V; node++)
// fout << bellman[node] << '\n';
}
int minCostMaxFlow(int src, int dest){
source = src;
sink = dest;
visited.resize(V+2);
parent.resize(V+2);
dist.resize(V+2);
addAuxNode();
bellmanFord(V+1);
recreateGraph();
//printGraph();
int maxFlow = 0, minCost = 0, flow;
while(dijkstra(source, sink) == true){
for(int &it: edge[sink]){
if(visited[it] == true and dist[sink] == dist[it] + cost[it][sink] and cap[it][sink] > 0){
flow = 1e8;
parent[sink] = it;
for(int node = sink; node != source and flow; node = parent[node])
flow = std::min(flow, cap[parent[node]][node]);
for(int node = sink; node != source and flow; node = parent[node]){
cap[parent[node]][node] -= flow;
cap[node][parent[node]] += flow;
minCost += flow * (cost[parent[node]][node] - bellman[parent[node]] + bellman[node]);
}
maxFlow += flow;
}
}
}
//fout << maxFlow << '\n';
return minCost;
}
};
void readInput(){
int V, E, source, sink;
fin >> V >> E >> source >> sink;
Graph graph(V);
for(int i=0, src, dest, cap, weight; i<E; i++){
fin >> src >> dest >> cap >> weight;
graph.addEdge(src, dest, cap, weight);
}
//graph.bellmanFord(1);
fout << graph.minCostMaxFlow(source, sink);
}
int main(){
readInput();
return 0;
}