From 5f02bf5efb1ae4a1e52af4f3578cac57f2d60d14 Mon Sep 17 00:00:00 2001 From: hizenberg Date: Fri, 2 Feb 2024 15:08:26 +0000 Subject: [PATCH] added Advanced Graph Algorithm --- Advanced Graph Algorithm/Ford_Fulkerson.cpp | 183 ++++++++++++++++++++ cpadv.cpp | 173 ++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 Advanced Graph Algorithm/Ford_Fulkerson.cpp create mode 100644 cpadv.cpp diff --git a/Advanced Graph Algorithm/Ford_Fulkerson.cpp b/Advanced Graph Algorithm/Ford_Fulkerson.cpp new file mode 100644 index 0000000..86d70a3 --- /dev/null +++ b/Advanced Graph Algorithm/Ford_Fulkerson.cpp @@ -0,0 +1,183 @@ +#include + +//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> 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> 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 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> resultGraph = solver->getGraph(); + + for(vector edges : resultGraph ){ + for( Edge* e : edges){ + cout << e->toString(s,t) << '\n'; + } + } + return 0; +} diff --git a/cpadv.cpp b/cpadv.cpp new file mode 100644 index 0000000..8a1afbf --- /dev/null +++ b/cpadv.cpp @@ -0,0 +1,173 @@ +#include +//#include + +//using namespace __gnu_pbds; +using namespace std; + +// template +// using indexed_multiset = tree , rb_tree_tag , + // tree_order_statistics_node_update>; +// template +// using indexed_set=tree,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 +#define sll set +#define vi vector +#define vll vector +#define pii pair +#define pll pair +#define vpi vector +#define vpl vector +#define mii map +#define mll map +#define sz(x) ((int) x.size()) +#define all(p) p.begin(), p.end() +#define que_max priority_queue +#define que_max_ll priority_queue +#define que_min priority_queue > +#define que_min_ll priority_queue > +#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 +T modMul(T a,T b,T M=(int)1e9+7){ + return ((a%M)*(b%M))%M; +} + +template +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 +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 +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 +void __f (const char* name, Arg1&& arg1) { cout << name << " : " << arg1 << endl; } +template +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 void _print (T t) { cerr << t; } +void _print() {return;} + +template void _print(T a[], int n) { cerr << "[ "; for(int i = 0; i < n; i++) { _print(a[i]); cerr << " "; } cerr << "]"; } +template void _print(pair p) {cerr << "{"; _print(p.first); cerr << ","; _print(p.second); cerr << "}";} +template void _print(vector v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} +template void _print(set v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} +template void _print(multiset v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} +template void _print(unordered_map v) {cerr << "[ "; for (auto &i : v) {_print(i); cerr << " ";} cerr << "]";} +template void _print(map v) {cerr << "[ "; for (auto &i : v) {_print(i); cerr << " ";} cerr << "]";} +template void _print(deque v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} +template void _print(queue q) {cerr << "[ "; while (!q.empty()) {_print(q.front()); cerr << " "; q.pop();} cerr << "]";} +template void _print(stack s) {cerr << "[ "; stack t; while (!s.empty()) {t.push(s.top()); s.pop();} while (!t.empty()) {_print(t.top()); cerr << " "; t.pop();} cerr << "]";} +template void _print(priority_queue pq) {cerr << "[ "; while (!pq.empty()) {_print(pq.top()); cerr << " "; pq.pop();} cerr << "]";} +template void _print(priority_queue, greater> pq) {cerr << "[ "; while (!pq.empty()) {_print(pq.top()); cerr << " "; pq.pop();} cerr << "]";} + +template void _print(T t, V... v) {_print(t); if(sizeof...(v)) {cerr<<", "; _print(v...);}} +// template void _print(oset 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; +} \ No newline at end of file