Pagini recente » Cod sursa (job #2898912) | Cod sursa (job #1877494) | Cod sursa (job #2565677) | Cod sursa (job #2735456) | Cod sursa (job #2957774)
#include <vector>
#include <queue>
#include <fstream>
#include <climits>
#include <iostream>
using namespace std;
ifstream fileIn("harta.in");
ofstream fileOut("harta.out");
class Graph {
protected:
int N;
int M;
vector<int> prev_in_bfs;
vector<vector<int>> list_adj;
vector<bool> visited;
vector<vector<int>> capacities;
public:
virtual void read();
void initialize(int k, int initial_capacity = 0);
int bfs(int s, int t);
int maxflow(int source, int target);
int getNoNodes() const{
return N;
}
};
void Graph::initialize(int k, int initial_capacity) {
list_adj.resize(k);
visited.resize(k);
prev_in_bfs.resize(k);
capacities.resize(k);
for(int i = 0; i < (int) capacities.size(); ++i) {
capacities[i].resize(k, initial_capacity);
}
}
void Graph:: read() {
fileIn >> N >> M;
initialize(N+1);
int a, b, c;
for(int i=1; i<= M; i++) {
fileIn >> a >> b >> c;
list_adj[a].push_back(b);
list_adj[b].push_back(a);
capacities[a][b] = c;
}
}
int Graph::bfs(int s, int t) {
//filling prev and visited vectors with default values
fill(prev_in_bfs.begin(), prev_in_bfs.end(), -2);
fill(visited.begin(), visited.end(), false);
// queue for bfs
queue<pair<int,int>> q_bfs;
//visiting the start node and adding to the queue
q_bfs.emplace(s, INT_MAX);
visited[s] = true;
prev_in_bfs[s] = -1;
int bottleneck;
while(!q_bfs.empty()) {
auto curr = q_bfs.front();
int curr_node = curr.first;
int curr_flow = curr.second;
q_bfs.pop();
for( auto node: list_adj[curr_node]) {
// for every adj node
int flow = capacities[curr_node][node];
if(!visited[node] && flow > 0) { // if the node it s not visited in this bfs and the edge have capacity
//we visit it and set its prev node
visited[node] = true;
prev_in_bfs[node] = curr_node;
//we calculate bottleneck as minimum on the current path from source to target
bottleneck = min(curr_flow, flow);
if (node == t) {
return bottleneck;
}
q_bfs.emplace(node, bottleneck);
}
}
}
return 0;
}
int Graph::maxflow(int source, int target) {
int flow = 0;
int bottleneck;
bottleneck = bfs(source,target);
while(bottleneck !=0) {
flow += bottleneck;
// traverse the path in reverse order to update capacity
for(int curr_node = target; curr_node != source; curr_node = prev_in_bfs[curr_node]) {
capacities[prev_in_bfs[curr_node]][curr_node] -= bottleneck; //decreasing forward edge capacity
capacities[curr_node][prev_in_bfs[curr_node]] += bottleneck; // increasing the reversed edge capacity
}
bottleneck = bfs(source, target);
}
return flow;
}
class Cuplaj2: public Graph {
//int E;
public:
void read() override;
void display_path();
};
void Cuplaj2 ::read() {
fileIn >> N ;
initialize(2 * N + 2, 0);
int start = 0;
int target = 2 * N +1;
int a, b;
for(int i = 1; i <= N; ++i) {
fileIn >> a >> b;
// de la start la i cu costul a
list_adj[start].push_back(i);
list_adj[i].push_back(0);
capacities[start][i] = a;
//de la i la toate fara i cu costul 1
for(int j = N + 1; j <= 2 * N ; ++j) {
if (i == j - N) continue;
list_adj[i].push_back(j);
list_adj[j].push_back(i);
capacities[i][j] = 1;
}
//de la N + i la target cu costul b
list_adj[N + i].push_back(target);
list_adj[target].push_back(N + i);
capacities[N + i][target] = b;
}
}
void Cuplaj2::display_path() {
int start = 0, target = 2 * N + 1;
fileOut << maxflow(start, target)<<'\n';
queue<int> q;
q.push(start);
for(auto elem_first_partition: list_adj[start]) {
for(auto elem_snd_partition: list_adj[elem_first_partition]){
if (elem_snd_partition == start) {
continue;
}
if (capacities[elem_first_partition][elem_snd_partition] == 0) {
fileOut << elem_first_partition << ' ' <<elem_snd_partition - N<< '\n';
capacities[elem_first_partition][elem_snd_partition]++;
}
}
}
}
int main() {
Cuplaj2 my_graph;
my_graph.read();
my_graph.display_path();
return 0;
}