Pagini recente » Cod sursa (job #54559) | Cod sursa (job #500994) | Cod sursa (job #3195805) | Cod sursa (job #42311) | Cod sursa (job #2957414)
//Idee agloritm: Pentru aceasta problema folosesc algoritmul Edmond-Karp.
//Folosim bfs pentru a gasi pe rand cate un drum de la sursa la destinatie(BFS in loc de DFS pentru a gasi nu orice drum, ci cel mai scurt drum).
//In functia BFS, la parcurgerea vecinilor unui nod verificam daca am ajuns la destinatie, iar daca am ajuns returnam 1 pentru ca am gasit un drum.
//Dupa ce am gasit drumul gasim capacitatea reziduala minima de pe acel drum si modificam capacitatile din graful rezidual
//(eu am facut asta folosind aceeasi matrice de capacitati de la inceput). La final afisam fluxul maxim rezultat si folosim DFS pentru a gasi taietura minima.
//Ea e formata din 2 submultimi: din prima submultime facand parte nodul de start si nodurile in care se poate ajunge din acesta(capacitatea pe acea muchie nu e 0)
//si a doua submultime contine restul nodurilor care cuprinde si nodul destinatie.
//Complexitate: O(n*m^2)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#define max_capacity 110001
using namespace std;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
int n, m, x, y, cap, max_flow;
int capacity[1001][1001];
vector<int>parent, visited;
vector<int>adjacency_list[1001];
queue<int>q;
vector<int>sel;
vector<int>min_cut;
int bfs(){
visited.assign(n+1, 0);
parent.assign(n+1, 0);
while(!q.empty()){
q.pop();
}
q.push(1);
visited[1]=1;
parent[1]=1;
while(!q.empty()){
int node=q.front();
q.pop();
for(auto neighbour:adjacency_list[node]){
if(visited[neighbour]==0 && capacity[node][neighbour]>0) {
q.push(neighbour);
parent[neighbour]=node;
visited[neighbour]=1;
if(neighbour == n) return 1;
}
}
}
return visited[n];
}
void dfs(int nod){
visited[nod]=1;
min_cut.push_back(nod);
for(auto neighbour: adjacency_list[nod]){
if(visited[neighbour] == 0 && capacity[nod][neighbour] > 0)
dfs(neighbour);
}
}
int main() {
fin>>n>>m;
//sel.assign(n+1, 0);
for(int i=1; i<=m; i++){
fin>>x>>y>>cap;
capacity[x][y] = cap;
adjacency_list[x].push_back(y);
adjacency_list[y].push_back(x);
}
while(bfs()) {
for (auto node: adjacency_list[n]) {
if (!visited[node]) //daca nodul nu face parte din drumul obtinut cu bfs
continue;
parent[n] = node;
int flow = max_capacity;
for (node = n; node != 1; node = parent[node]) {
flow = min(flow, capacity[parent[node]][node]);
}
if (flow == 0) continue;
for (node = n; node != 1; node = parent[node]) {
capacity[parent[node]][node] -= flow;
capacity[node][parent[node]] += flow;
}
max_flow += flow;
}
}
fout<<max_flow;
visited.assign(n+1, 0);
dfs(1);
cout<<"MINIMUM CUT:\n";
for(int i=0; i < min_cut.size(); i++)
cout << min_cut[i] << " ";
cout<<'\n';
for(int i=1; i<=n; i++){
if(find(min_cut.begin(), min_cut.end(), i) == min_cut.end()){
cout<<i<<" ";
}
}
return 0;
}