mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-07-16 11:32:44 +08:00
rename Graph -> graph (#649)
This commit is contained in:
73
graph/BFS.cpp
Normal file
73
graph/BFS.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
class graph
|
||||
{
|
||||
int v;
|
||||
list<int> *adj;
|
||||
|
||||
public:
|
||||
graph(int v);
|
||||
void addedge(int src, int dest);
|
||||
void printgraph();
|
||||
void bfs(int s);
|
||||
};
|
||||
graph::graph(int v)
|
||||
{
|
||||
this->v = v;
|
||||
this->adj = new list<int>[v];
|
||||
}
|
||||
void graph::addedge(int src, int dest)
|
||||
{
|
||||
src--;
|
||||
dest--;
|
||||
adj[src].push_back(dest);
|
||||
//adj[dest].push_back(src);
|
||||
}
|
||||
void graph::printgraph()
|
||||
{
|
||||
for (int i = 0; i < this->v; i++)
|
||||
{
|
||||
cout << "Adjacency list of vertex " << i + 1 << " is \n";
|
||||
list<int>::iterator it;
|
||||
for (it = adj[i].begin(); it != adj[i].end(); ++it)
|
||||
{
|
||||
cout << *it + 1 << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
void graph::bfs(int s)
|
||||
{
|
||||
bool *visited = new bool[this->v + 1];
|
||||
memset(visited, false, sizeof(bool) * (this->v + 1));
|
||||
visited[s] = true;
|
||||
list<int> q;
|
||||
q.push_back(s);
|
||||
list<int>::iterator it;
|
||||
while (!q.empty())
|
||||
{
|
||||
int u = q.front();
|
||||
cout << u << " ";
|
||||
q.pop_front();
|
||||
for (it = adj[u].begin(); it != adj[u].end(); ++it)
|
||||
{
|
||||
if (visited[*it] == false)
|
||||
{
|
||||
visited[*it] = true;
|
||||
q.push_back(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
graph g(4);
|
||||
g.addedge(1, 2);
|
||||
g.addedge(2, 3);
|
||||
g.addedge(3, 4);
|
||||
g.addedge(1, 4);
|
||||
g.addedge(1, 3);
|
||||
//g.printgraph();
|
||||
g.bfs(2);
|
||||
return 0;
|
||||
}
|
||||
31
graph/DFS.cpp
Normal file
31
graph/DFS.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
int v = 4;
|
||||
void DFSUtil_(int graph[4][4], bool visited[], int s)
|
||||
{
|
||||
visited[s] = true;
|
||||
cout << s << " ";
|
||||
for (int i = 0; i < v; i++)
|
||||
{
|
||||
if (graph[s][i] == 1 && visited[i] == false)
|
||||
{
|
||||
DFSUtil_(graph, visited, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DFS_(int graph[4][4], int s)
|
||||
{
|
||||
bool visited[v];
|
||||
memset(visited, 0, sizeof(visited));
|
||||
DFSUtil_(graph, visited, s);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int graph[4][4] = {{0, 1, 1, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}, {0, 0, 0, 1}};
|
||||
cout << "DFS: ";
|
||||
DFS_(graph, 2);
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
57
graph/DFS_with_stack.cc
Normal file
57
graph/DFS_with_stack.cc
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <stack>
|
||||
|
||||
#define WHITE 0
|
||||
#define GREY 1
|
||||
#define BLACK 2
|
||||
#define INF 99999
|
||||
|
||||
using namespace std;
|
||||
|
||||
int checked[999] = {WHITE};
|
||||
|
||||
void dfs(const list<int> lista[], int start)
|
||||
{
|
||||
stack<int> stack;
|
||||
|
||||
int checked[999] = {WHITE};
|
||||
|
||||
stack.push(start);
|
||||
|
||||
checked[start] = GREY;
|
||||
while (!stack.empty())
|
||||
{
|
||||
int act = stack.top();
|
||||
stack.pop();
|
||||
|
||||
if (checked[act] == GREY)
|
||||
{
|
||||
cout << act << ' ';
|
||||
for (auto it = lista[act].begin(); it != lista[act].end(); ++it)
|
||||
{
|
||||
stack.push(*it);
|
||||
if (checked[*it] != BLACK)
|
||||
checked[*it] = GREY;
|
||||
}
|
||||
checked[act] = BLACK; //nodo controllato
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int u, w;
|
||||
int n;
|
||||
cin >> n;
|
||||
list<int> lista[INF];
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
cin >> u >> w;
|
||||
lista[u].push_back(w);
|
||||
}
|
||||
|
||||
dfs(lista, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
55
graph/Dijkstra.cpp
Normal file
55
graph/Dijkstra.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define INF 10000010
|
||||
vector<pair<int, int>> graph[5 * 100001];
|
||||
int dis[5 * 100001];
|
||||
int dij(vector<pair<int, int>> *v, int s, int *dis)
|
||||
{
|
||||
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
|
||||
// source distance to zero.
|
||||
pq.push(make_pair(0, s));
|
||||
dis[s] = 0;
|
||||
int u;
|
||||
while (!pq.empty())
|
||||
{
|
||||
u = (pq.top()).second;
|
||||
pq.pop();
|
||||
for (vector<pair<int, int>>::iterator it = v[u].begin(); it != v[u].end(); it++)
|
||||
{
|
||||
if (dis[u] + it->first < dis[it->second])
|
||||
{
|
||||
dis[it->second] = dis[u] + it->first;
|
||||
pq.push(make_pair(dis[it->second], it->second));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
int m, n, l, x, y, s;
|
||||
// n--> number of nodes , m --> number of edges
|
||||
cin >> n >> m;
|
||||
for (int i = 0; i < m; i++)
|
||||
{
|
||||
// input edges.
|
||||
scanf("%d%d%d", &x, &y, &l);
|
||||
graph[x].push_back(make_pair(l, y));
|
||||
graph[y].push_back(make_pair(l, x)); // comment this line for directed graph
|
||||
}
|
||||
// start node.
|
||||
scanf("%d", &s);
|
||||
// intialise all distances to infinity.
|
||||
for (int i = 1; i <= n; i++)
|
||||
dis[i] = INF;
|
||||
dij(graph, s, dis);
|
||||
|
||||
for (int i = 1; i <= n; i++)
|
||||
if (dis[i] == INF)
|
||||
cout << "-1 ";
|
||||
else
|
||||
cout << dis[i] << " ";
|
||||
return 0;
|
||||
}
|
||||
135
graph/Kruskal.cpp
Normal file
135
graph/Kruskal.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include "bits/stdc++.h"
|
||||
//#include <boost/multiprecision/cpp_int.hpp>
|
||||
//using namespace boost::multiprecision;
|
||||
const int mx = 1e6 + 5;
|
||||
const long int inf = 2e9;
|
||||
typedef long long ll;
|
||||
#define rep(i, n) for (i = 0; i < n; i++)
|
||||
#define repp(i, a, b) for (i = a; i <= b; i++)
|
||||
#define pii pair<int, int>
|
||||
#define vpii vector<pii>
|
||||
#define vi vector<int>
|
||||
#define vll vector<ll>
|
||||
#define r(x) scanf("%d", &x)
|
||||
#define rs(s) scanf("%s", s)
|
||||
#define gc getchar_unlocked
|
||||
#define pc putchar_unlocked
|
||||
#define mp make_pair
|
||||
#define pb push_back
|
||||
#define lb lower_bound
|
||||
#define ub upper_bound
|
||||
#define endl "\n"
|
||||
#define fast \
|
||||
ios_base::sync_with_stdio(false); \
|
||||
cin.tie(NULL); \
|
||||
cout.tie(NULL);
|
||||
using namespace std;
|
||||
void in(int &x)
|
||||
{
|
||||
register int c = gc();
|
||||
x = 0;
|
||||
int neg = 0;
|
||||
for (; ((c < 48 || c > 57) && c != '-'); c = gc())
|
||||
;
|
||||
if (c == '-')
|
||||
{
|
||||
neg = 1;
|
||||
c = gc();
|
||||
}
|
||||
for (; c > 47 && c < 58; c = gc())
|
||||
{
|
||||
x = (x << 1) + (x << 3) + c - 48;
|
||||
}
|
||||
if (neg)
|
||||
x = -x;
|
||||
}
|
||||
void out(int n)
|
||||
{
|
||||
int N = n, rev, count = 0;
|
||||
rev = N;
|
||||
if (N == 0)
|
||||
{
|
||||
pc('0');
|
||||
return;
|
||||
}
|
||||
while ((rev % 10) == 0)
|
||||
{
|
||||
count++;
|
||||
rev /= 10;
|
||||
}
|
||||
rev = 0;
|
||||
while (N != 0)
|
||||
{
|
||||
rev = (rev << 3) + (rev << 1) + N % 10;
|
||||
N /= 10;
|
||||
}
|
||||
while (rev != 0)
|
||||
{
|
||||
pc(rev % 10 + '0');
|
||||
rev /= 10;
|
||||
}
|
||||
while (count--)
|
||||
pc('0');
|
||||
}
|
||||
ll parent[mx], arr[mx], node, edge;
|
||||
vector<pair<ll, pair<ll, ll>>> v;
|
||||
void initial()
|
||||
{
|
||||
int i;
|
||||
rep(i, node + edge)
|
||||
parent[i] = i;
|
||||
}
|
||||
int root(int i)
|
||||
{
|
||||
while (parent[i] != i)
|
||||
{
|
||||
parent[i] = parent[parent[i]];
|
||||
i = parent[i];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
void join(int x, int y)
|
||||
{
|
||||
int root_x = root(x); //Disjoint set union by rank
|
||||
int root_y = root(y);
|
||||
parent[root_x] = root_y;
|
||||
}
|
||||
ll kruskal()
|
||||
{
|
||||
ll mincost = 0, i, x, y;
|
||||
rep(i, edge)
|
||||
{
|
||||
x = v[i].second.first;
|
||||
y = v[i].second.second;
|
||||
if (root(x) != root(y))
|
||||
{
|
||||
mincost += v[i].first;
|
||||
join(x, y);
|
||||
}
|
||||
}
|
||||
return mincost;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
fast;
|
||||
while (1)
|
||||
{
|
||||
int i, j, from, to, cost, totalcost = 0;
|
||||
cin >> node >> edge; //Enter the nodes and edges
|
||||
if (node == 0 && edge == 0)
|
||||
break; //Enter 0 0 to break out
|
||||
initial(); //Initialise the parent array
|
||||
rep(i, edge)
|
||||
{
|
||||
cin >> from >> to >> cost;
|
||||
v.pb(mp(cost, mp(from, to)));
|
||||
totalcost += cost;
|
||||
}
|
||||
sort(v.begin(), v.end());
|
||||
// rep(i,v.size())
|
||||
// cout<<v[i].first<<" ";
|
||||
cout << kruskal() << endl;
|
||||
v.clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
53
graph/Topological-Sort.cpp
Normal file
53
graph/Topological-Sort.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
int n, m; // For number of Vertices (V) and number of edges (E)
|
||||
vector<vector<int>> G;
|
||||
vector<bool> visited;
|
||||
vector<int> ans;
|
||||
|
||||
void dfs(int v)
|
||||
{
|
||||
visited[v] = true;
|
||||
for (int u : G[v])
|
||||
{
|
||||
if (!visited[u])
|
||||
dfs(u);
|
||||
}
|
||||
ans.push_back(v);
|
||||
}
|
||||
|
||||
void topological_sort()
|
||||
{
|
||||
visited.assign(n, false);
|
||||
ans.clear();
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (!visited[i])
|
||||
dfs(i);
|
||||
}
|
||||
reverse(ans.begin(), ans.end());
|
||||
}
|
||||
int main()
|
||||
{
|
||||
cout << "Enter the number of vertices and the number of directed edges\n";
|
||||
cin >> n >> m;
|
||||
int x, y;
|
||||
G.resize(n, vector<int>());
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
cin >> x >> y;
|
||||
x--, y--; // to convert 1-indexed to 0-indexed
|
||||
G[x].push_back(y);
|
||||
}
|
||||
topological_sort();
|
||||
cout << "Topological Order : \n";
|
||||
for (int v : ans)
|
||||
{
|
||||
cout << v + 1 << ' '; // converting zero based indexing back to one based.
|
||||
}
|
||||
cout << '\n';
|
||||
return 0;
|
||||
}
|
||||
134
graph/kosaraju.cpp
Normal file
134
graph/kosaraju.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/* Implementation of Kosaraju's Algorithm to find out the strongly connected components (SCCs) in a graph.
|
||||
Author:Anirban166
|
||||
*/
|
||||
|
||||
#include<iostream>
|
||||
#include<vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Iterative function/method to print graph:
|
||||
* @param a[] : array of vectors (2D)
|
||||
* @param V : vertices
|
||||
* @return void
|
||||
**/
|
||||
void print(vector<int> a[],int V)
|
||||
{
|
||||
for(int i=0;i<V;i++)
|
||||
{
|
||||
if(!a[i].empty())
|
||||
cout<<"i="<<i<<"-->";
|
||||
for(int j=0;j<a[i].size();j++)
|
||||
cout<<a[i][j]<<" ";
|
||||
if(!a[i].empty())
|
||||
cout<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* //Recursive function/method to push vertices into stack passed as parameter:
|
||||
* @param v : vertices
|
||||
* @param &st : stack passed by reference
|
||||
* @param vis[] : array to keep track of visited nodes (boolean type)
|
||||
* @param adj[] : array of vectors to represent graph
|
||||
* @return void
|
||||
**/
|
||||
void push_vertex(int v,stack<int> &st,bool vis[],vector<int> adj[])
|
||||
{
|
||||
vis[v]=true;
|
||||
for(auto i=adj[v].begin();i!=adj[v].end();i++)
|
||||
{
|
||||
if(vis[*i]==false)
|
||||
push_vertex(*i,st,vis,adj);
|
||||
}
|
||||
st.push(v);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* //Recursive function/method to implement depth first traversal(dfs):
|
||||
* @param v : vertices
|
||||
* @param vis[] : array to keep track of visited nodes (boolean type)
|
||||
* @param grev[] : graph with reversed edges
|
||||
* @return void
|
||||
**/
|
||||
void dfs(int v,bool vis[],vector<int> grev[])
|
||||
{
|
||||
vis[v]=true;
|
||||
// cout<<v<<" ";
|
||||
for(auto i=grev[v].begin();i!=grev[v].end();i++)
|
||||
{
|
||||
if(vis[*i]==false)
|
||||
dfs(*i,vis,grev);
|
||||
}
|
||||
}
|
||||
|
||||
//function/method to implement Kosaraju's Algorithm:
|
||||
/**
|
||||
* Info about the method
|
||||
* @param V : vertices in graph
|
||||
* @param adj[] : array of vectors that represent a graph (adjacency list/array)
|
||||
* @return int ( 0, 1, 2..and so on, only unsigned values as either there can be no SCCs i.e. none(0) or there will be x no. of SCCs (x>0))
|
||||
i.e. it returns the count of (number of) strongly connected components (SCCs) in the graph. (variable 'count_scc' within function)
|
||||
**/
|
||||
int kosaraju(int V, vector<int> adj[])
|
||||
{
|
||||
bool vis[V]={};
|
||||
stack<int> st;
|
||||
for(int v=0;v<V;v++)
|
||||
{
|
||||
if(vis[v]==false)
|
||||
push_vertex(v,st,vis,adj);
|
||||
}
|
||||
//making new graph (grev) with reverse edges as in adj[]:
|
||||
vector<int> grev[V];
|
||||
for(int i=0;i<V+1;i++)
|
||||
{
|
||||
for(auto j=adj[i].begin();j!=adj[i].end();j++)
|
||||
{
|
||||
grev[*j].push_back(i);
|
||||
}
|
||||
}
|
||||
// cout<<"grev="<<endl; ->debug statement
|
||||
// print(grev,V); ->debug statement
|
||||
//reinitialise visited to 0
|
||||
for(int i=0;i<V;i++)
|
||||
vis[i]=false;
|
||||
int count_scc=0;
|
||||
while(!st.empty())
|
||||
{
|
||||
int t=st.top();
|
||||
st.pop();
|
||||
if(vis[t]==false)
|
||||
{
|
||||
dfs(t,vis,grev);
|
||||
count_scc++;
|
||||
}
|
||||
}
|
||||
// cout<<"count_scc="<<count_scc<<endl; //in case you want to print here itself, uncomment & change return type of function to void.
|
||||
return count_scc;
|
||||
}
|
||||
|
||||
//All critical/corner cases have been taken care of.
|
||||
//Input your required values: (not hardcoded)
|
||||
int main()
|
||||
{
|
||||
int t;
|
||||
cin>>t;
|
||||
while(t--)
|
||||
{
|
||||
int a,b ; //a->number of nodes, b->directed edges.
|
||||
cin>>a>>b;
|
||||
int m,n;
|
||||
vector<int> adj[a+1];
|
||||
for(int i=0;i<b;i++) //take total b inputs of 2 vertices each required to form an edge.
|
||||
{
|
||||
cin>>m>>n; //take input m,n denoting edge from m->n.
|
||||
adj[m].push_back(n);
|
||||
}
|
||||
//pass number of nodes and adjacency array as parameters to function:
|
||||
cout<<kosaraju(a, adj)<<endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
120
graph/lca.cpp
Normal file
120
graph/lca.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include<bits/stdc++.h>
|
||||
|
||||
using namespace std;
|
||||
// Find the lowest common ancestor using binary lifting in O(nlogn)
|
||||
// Zero based indexing
|
||||
// Resource : https://cp-algorithms.com/graph/lca_binary_lifting.html
|
||||
const int N = 1005;
|
||||
const int LG = log2(N) + 1;
|
||||
struct lca
|
||||
{
|
||||
int n;
|
||||
vector<int> adj[N]; // Graph
|
||||
int up[LG][N]; // build this table
|
||||
int level[N]; // get the levels of all of them
|
||||
|
||||
lca(int n_): n(n_)
|
||||
{
|
||||
memset(up, -1, sizeof(up));
|
||||
memset(level, 0, sizeof(level));
|
||||
for (int i = 0; i < n - 1; ++i)
|
||||
{
|
||||
int a, b;
|
||||
cin >> a >> b;
|
||||
a--;
|
||||
b--;
|
||||
adj[a].push_back(b);
|
||||
adj[b].push_back(a);
|
||||
}
|
||||
level[0] = 0;
|
||||
dfs(0, -1);
|
||||
build();
|
||||
}
|
||||
void verify()
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
cout << i << " : level: " << level[i] << endl;
|
||||
}
|
||||
cout << endl;
|
||||
for (int i = 0; i < LG; ++i)
|
||||
{
|
||||
cout << "Power:" << i << ": ";
|
||||
for (int j = 0; j < n; ++j)
|
||||
{
|
||||
cout << up[i][j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void build()
|
||||
{
|
||||
for (int i = 1; i < LG; ++i)
|
||||
{
|
||||
for (int j = 0; j < n; ++j)
|
||||
{
|
||||
if (up[i - 1][j] != -1)
|
||||
{
|
||||
up[i][j] = up[i - 1][up[i - 1][j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dfs(int node, int par)
|
||||
{
|
||||
up[0][node] = par;
|
||||
for (auto i: adj[node])
|
||||
{
|
||||
if (i != par)
|
||||
{
|
||||
level[i] = level[node] + 1;
|
||||
dfs(i, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
int query(int u, int v)
|
||||
{
|
||||
u--;
|
||||
v--;
|
||||
if (level[v] > level[u])
|
||||
{
|
||||
swap(u, v);
|
||||
}
|
||||
// u is at the bottom.
|
||||
int dist = level[u] - level[v];
|
||||
// Go up this much distance
|
||||
for (int i = LG - 1; i >= 0; --i)
|
||||
{
|
||||
if (dist & (1 << i))
|
||||
{
|
||||
u = up[i][u];
|
||||
}
|
||||
}
|
||||
if (u == v)
|
||||
{
|
||||
return u;
|
||||
}
|
||||
assert(level[u] == level[v]);
|
||||
for (int i = LG - 1; i >= 0; --i)
|
||||
{
|
||||
if (up[i][u] != up[i][v])
|
||||
{
|
||||
u = up[i][u];
|
||||
v = up[i][v];
|
||||
}
|
||||
}
|
||||
assert(up[0][u] == up[0][v]);
|
||||
return up[0][u];
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int n; // number of nodes in the tree.
|
||||
lca l(n); // will take the input in the format given
|
||||
// n-1 edges of the form
|
||||
// a b
|
||||
// Use verify function to see.
|
||||
}
|
||||
Reference in New Issue
Block a user