mirror of
https://github.com/Hizenberg469/Algorithms-snippets.git
synced 2026-04-19 22:52:23 +03:00
added Advanced Graph Algorithm
This commit is contained in:
183
Advanced Graph Algorithm/Ford_Fulkerson.cpp
Normal file
183
Advanced Graph Algorithm/Ford_Fulkerson.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
#include <bits/stdc++.h>
|
||||
|
||||
//used for ignoring/removing the assert statement at compile-time.
|
||||
//#define NDEBUG
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Edge{
|
||||
public:
|
||||
int from, to;
|
||||
Edge* residual;
|
||||
long flow;
|
||||
long capacity;
|
||||
|
||||
Edge(int from, int to, long capacity){
|
||||
this->from = from;
|
||||
this->to = to;
|
||||
this->capacity = capacity;
|
||||
flow = 0;
|
||||
}
|
||||
|
||||
bool isResidual(){
|
||||
return capacity == 0;
|
||||
}
|
||||
|
||||
long remainingCapacity(){
|
||||
return capacity - flow;
|
||||
}
|
||||
|
||||
void augment(long bottleNeck){
|
||||
flow += bottleNeck;
|
||||
residual->flow -= bottleNeck;
|
||||
}
|
||||
|
||||
string toString(int s ,int t){
|
||||
string u = (from == s) ? "s" : ((from == t) ? "t" : to_string(from));
|
||||
string v = (to == s ) ? "s" : ((to == t) ? "t" : to_string(to));
|
||||
string res = "Edge " + u + " -> " + v + " | " + " flow = " +
|
||||
to_string(flow) + " | " + " capacity: " + to_string(capacity)
|
||||
+ " | " + " is residual: " + to_string((int)isResidual()) ;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
class NetworkFlowSolverBase{
|
||||
protected :
|
||||
long INF = INT_MAX/2;
|
||||
//Input: n = Number of nodes, s = source, t = sink
|
||||
int n , s, t;
|
||||
|
||||
//'visited' and 'visitedToken' are keep track of the
|
||||
//visited nodes.
|
||||
protected:
|
||||
int visitedToken = 1;
|
||||
int* visited;
|
||||
|
||||
|
||||
bool solved;
|
||||
long maxFlow;
|
||||
|
||||
//Representing the graph.
|
||||
vector<vector<Edge*>> graph;
|
||||
|
||||
public:
|
||||
|
||||
NetworkFlowSolverBase(int n, int s,int t){
|
||||
this->n = n;
|
||||
this->s = s;
|
||||
this->t = t;
|
||||
graph.resize(n);
|
||||
visited = new int[n];
|
||||
}
|
||||
|
||||
void addEdge(int from ,int to ,long capacity){
|
||||
assert(capacity > 0);
|
||||
|
||||
Edge* e1 = new Edge(from, to , capacity);
|
||||
Edge* e2 = new Edge(to, from, 0);
|
||||
e1->residual = e2;
|
||||
e2->residual = e1;
|
||||
graph[from].push_back(e1);
|
||||
graph[to].push_back(e2);
|
||||
}
|
||||
|
||||
vector<vector<Edge*>> getGraph(){
|
||||
execute();
|
||||
return graph;
|
||||
}
|
||||
|
||||
long getMaxFlow(){
|
||||
execute();
|
||||
return maxFlow;
|
||||
}
|
||||
|
||||
private :
|
||||
void execute(){
|
||||
if( solved )return;
|
||||
solved = true;
|
||||
solve();
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void solve(){}
|
||||
};
|
||||
|
||||
|
||||
class FordFulkersonDfsSolver : public NetworkFlowSolverBase{
|
||||
public :
|
||||
FordFulkersonDfsSolver(int n, int s, int t) : NetworkFlowSolverBase(n,s,t){
|
||||
}
|
||||
|
||||
void solve(){
|
||||
for( long f = dfs(s, INF) ; f != 0 ; f = dfs(s,INF)){
|
||||
visitedToken++;
|
||||
maxFlow += f;
|
||||
}
|
||||
}
|
||||
|
||||
private :
|
||||
long dfs(int node, long flow){
|
||||
if( node == t )return flow;
|
||||
|
||||
visited[node] = visitedToken;
|
||||
|
||||
vector<Edge*> edges = graph[node];
|
||||
for(Edge* edge : edges){
|
||||
if( edge->remainingCapacity() > 0 && visited[edge->to] != visitedToken){
|
||||
long bottleNeck = dfs(edge->to , min(flow,edge->remainingCapacity()));
|
||||
|
||||
if( bottleNeck > 0){
|
||||
edge->augment(bottleNeck);
|
||||
return bottleNeck;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main(){
|
||||
|
||||
int n = 12;
|
||||
|
||||
int s = n - 2;
|
||||
int t = n - 1;
|
||||
|
||||
NetworkFlowSolverBase* solver = new FordFulkersonDfsSolver(n,s,t);
|
||||
|
||||
//Edges from Source
|
||||
solver->addEdge(s, 0, 10);
|
||||
solver->addEdge(s, 1, 5);
|
||||
solver->addEdge(s, 2, 10);
|
||||
|
||||
//Middle edges
|
||||
solver->addEdge(0, 3, 10);
|
||||
solver->addEdge(1, 2, 10);
|
||||
solver->addEdge(2, 5, 15);
|
||||
solver->addEdge(3, 1, 2);
|
||||
solver->addEdge(3, 6, 15);
|
||||
solver->addEdge(4, 1, 15);
|
||||
solver->addEdge(4, 3, 3);
|
||||
solver->addEdge(5, 4, 4);
|
||||
solver->addEdge(5, 8, 10);
|
||||
solver->addEdge(6, 7, 10);
|
||||
solver->addEdge(7, 4, 10);
|
||||
solver->addEdge(7, 5, 7);
|
||||
|
||||
//Edges to sink
|
||||
solver->addEdge(6, t, 15);
|
||||
solver->addEdge(8, t, 10);
|
||||
|
||||
cout << "Maximum Flow is: " << solver->getMaxFlow() << '\n';
|
||||
|
||||
vector<vector<Edge*>> resultGraph = solver->getGraph();
|
||||
|
||||
for(vector<Edge*> edges : resultGraph ){
|
||||
for( Edge* e : edges){
|
||||
cout << e->toString(s,t) << '\n';
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
173
cpadv.cpp
Normal file
173
cpadv.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
#include <bits/stdc++.h>
|
||||
//#include <ext/pb_ds/assoc_container.hpp>
|
||||
|
||||
//using namespace __gnu_pbds;
|
||||
using namespace std;
|
||||
|
||||
// template<typename T>
|
||||
// using indexed_multiset = tree<T , null_type , less_equal<T> , rb_tree_tag ,
|
||||
// tree_order_statistics_node_update>;
|
||||
// template<typename T>
|
||||
// using indexed_set=tree<T,null_type,less<T>,rb_tree_tag,
|
||||
// tree_order_statistics_node_update>;
|
||||
|
||||
#define ld long double
|
||||
#define ll long long int
|
||||
#define F first
|
||||
#define S second
|
||||
#define pb push_back
|
||||
#define si set <int>
|
||||
#define sll set <ll>
|
||||
#define vi vector <int>
|
||||
#define vll vector <ll>
|
||||
#define pii pair <int, int>
|
||||
#define pll pair <ll,ll>
|
||||
#define vpi vector <pii>
|
||||
#define vpl vector <pll>
|
||||
#define mii map <int, int>
|
||||
#define mll map <ll,ll>
|
||||
#define sz(x) ((int) x.size())
|
||||
#define all(p) p.begin(), p.end()
|
||||
#define que_max priority_queue <int>
|
||||
#define que_max_ll priority_queue <ll>
|
||||
#define que_min priority_queue <int, vi, greater<int>>
|
||||
#define que_min_ll priority_queue <ll , vll, greater<ll>>
|
||||
#define bug(...) __f (#__VA_ARGS__, __VA_ARGS__)
|
||||
#define print(a) for(auto x : a) cout << x << " "; cout << endl
|
||||
#define print1(a) for(auto x : a) cout << x.F << " " << x.S << endl
|
||||
#define print2(i,a,x,y) for(auto i = x; i < y; i++) cout<< a[i]<< " "; cout << endl
|
||||
#define scan(s,e,a) for(auto i = s ; i <= e ; i++ ) cin>>a[i]
|
||||
#define loop(i,s,e,weight) for(auto i = s ; (weight>=0? i <= e : i >= e ) ; i+=weight )
|
||||
#define read(n) ll n; cin>>n
|
||||
#define endl '\n'
|
||||
|
||||
//endl -> cout << '\n' << flush;//hence,slower.
|
||||
//for interactive problem.
|
||||
// cout << flush; //for cin cout
|
||||
// fflush(stdout); //for scanf printf.
|
||||
|
||||
//In Mathematics section of cp course.
|
||||
|
||||
template<typename T>
|
||||
T modMul(T a,T b,T M=(int)1e9+7){
|
||||
return ((a%M)*(b%M))%M;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T power(T a, T b, T M)
|
||||
{
|
||||
T x = 1;
|
||||
while (b)
|
||||
{
|
||||
if (b & 1) x = modMul(x,a,M);
|
||||
a = modMul(a,a,M);
|
||||
b >>= 1;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T pwr(T a, T b)
|
||||
{
|
||||
T x = 1;
|
||||
while (b)
|
||||
{
|
||||
if (b & 1) x = x*a;
|
||||
a = a*a;
|
||||
b >>= 1;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
//Square root using advanced binary search.
|
||||
template <typename T>
|
||||
ld sq_root(T x){
|
||||
|
||||
ld err = 1e-6;
|
||||
|
||||
ld ans;
|
||||
ld low = 1.0 , high = x;
|
||||
for(int i = 1 ; i <= 40 ; i++ ){
|
||||
ld mid = low + (high - low)/2.0;
|
||||
|
||||
if( mid*mid <= x ){
|
||||
ans = mid;
|
||||
low = mid + err;
|
||||
}
|
||||
else{
|
||||
high = mid - err;
|
||||
}
|
||||
}
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
template <typename Arg1>
|
||||
void __f (const char* name, Arg1&& arg1) { cout << name << " : " << arg1 << endl; }
|
||||
template <typename Arg1, typename... Args>
|
||||
void __f (const char* names, Arg1&& arg1, Args&&... args)
|
||||
{
|
||||
const char* comma = strchr (names + 1, ',');
|
||||
cout.write (names, comma - names) << " : " << arg1 << " "; __f (comma + 1, args...);
|
||||
}
|
||||
|
||||
/*******************************************************************Debugging tools *************************************************/
|
||||
#define dbg(x...) cerr << #x << " "; _print(x); cerr << endl;
|
||||
#define debug(x,y...) cerr << #x << " -> "; _print(y); cerr << endl;
|
||||
#define crndl cerr << "\n";
|
||||
|
||||
template <typename T> void _print (T t) { cerr << t; }
|
||||
void _print() {return;}
|
||||
|
||||
template <class T> void _print(T a[], int n) { cerr << "[ "; for(int i = 0; i < n; i++) { _print(a[i]); cerr << " "; } cerr << "]"; }
|
||||
template <class T, class V> void _print(pair <T, V> p) {cerr << "{"; _print(p.first); cerr << ","; _print(p.second); cerr << "}";}
|
||||
template <class T> void _print(vector <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
|
||||
template <class T> void _print(set <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
|
||||
template <class T> void _print(multiset <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
|
||||
template <class T, class V> void _print(unordered_map <T, V> v) {cerr << "[ "; for (auto &i : v) {_print(i); cerr << " ";} cerr << "]";}
|
||||
template <class T, class V> void _print(map <T, V> v) {cerr << "[ "; for (auto &i : v) {_print(i); cerr << " ";} cerr << "]";}
|
||||
template <class T> void _print(deque <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
|
||||
template <class T> void _print(queue <T> q) {cerr << "[ "; while (!q.empty()) {_print(q.front()); cerr << " "; q.pop();} cerr << "]";}
|
||||
template <class T> void _print(stack <T> s) {cerr << "[ "; stack<T> t; while (!s.empty()) {t.push(s.top()); s.pop();} while (!t.empty()) {_print(t.top()); cerr << " "; t.pop();} cerr << "]";}
|
||||
template <class T> void _print(priority_queue <T> pq) {cerr << "[ "; while (!pq.empty()) {_print(pq.top()); cerr << " "; pq.pop();} cerr << "]";}
|
||||
template <class T> void _print(priority_queue<T, vector<T>, greater<T>> pq) {cerr << "[ "; while (!pq.empty()) {_print(pq.top()); cerr << " "; pq.pop();} cerr << "]";}
|
||||
|
||||
template <class T, class... V> void _print(T t, V... v) {_print(t); if(sizeof...(v)) {cerr<<", "; _print(v...);}}
|
||||
// template <class T> void _print(oset<T> v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";}
|
||||
|
||||
/************************************************************************************************************************************/
|
||||
|
||||
const int N = 200005;
|
||||
/**********************Solve Here*********************/
|
||||
|
||||
void solve(){
|
||||
|
||||
}
|
||||
|
||||
/**********************Solve Here*********************/
|
||||
int32_t main()
|
||||
{
|
||||
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
|
||||
|
||||
// clock_t z = clock();
|
||||
|
||||
/***********************Test cases********************/
|
||||
|
||||
|
||||
int t = 1;
|
||||
// cin >> t;
|
||||
// int i=1;
|
||||
while (t--){
|
||||
// cout << "Case#" << i << endl;
|
||||
solve();
|
||||
// i++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************Test cases********************/
|
||||
// cerr << "Run Time : " << ((double)(clock() - z) / CLOCKS_PER_SEC);
|
||||
//cerr= c error.
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user