// C++ program to find K-Cores of a graph
#include<bits/stdc++.h>
using namespace std;
// This class represents a undirected graph using adjacency
// list representation
class Graph
{
int V; // No. of vertices
// Pointer to an array containing adjacency lists
list<int> *adj;
public:
Graph(int V); // Constructor
// function to add an edge to graph
void addEdge(int u, int v);
// A recursive function to print DFS starting from v
bool DFSUtil(int, vector<bool> &, vector<int> &, int k);
// prints k-Cores of given graph
void printKCores(int k);
};
// A recursive function to print DFS starting from v.
// It returns true if degree of v after processing is less
// than k else false
// It also updates degree of adjacent if degree of v
// is less than k. And if degree of a processed adjacent
// becomes less than k, then it reduces of degree of v also,
bool Graph::DFSUtil(int v, vector<bool> &visited,
vector<int> &vDegree, int k)
{
// Mark the current node as visited and print it
visited[v] = true;
cout<<v<<" degree: "<<vDegree[v]<<endl;
// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
{
// degree of v is less than k, then degree of adjacent
// must be reduced
if (vDegree[v] < k){
vDegree[*i]--;
cout<<*i<<" inside: "<<v<<" degree: "<<vDegree[*i]<<endl;
}
// If adjacent is not processed, process it
if (!visited[*i])
{
// If degree of adjacent after processing becomes
// less than k, then reduce degree of v also.
DFSUtil(*i, visited, vDegree, k);
}
}
// Return true if degree of v is less than k
return (vDegree[v] < k);
}
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int u, int v)
{
adj[u].push_back(v);
adj[v].push_back(u);
}
// Prints k cores of an undirected graph
void Graph::printKCores(int k)
{
// INITIALIZATION
// Mark all the vertices as not visited and not
// processed.
vector<bool> visited(V, false);
vector<bool> processed(V, false);
int mindeg = INT_MAX;
int startvertex;
// Store degrees of all vertices
vector<int> vDegree(V);
for (int i=0; i<V; i++)
{
vDegree[i] = adj[i].size();
if (vDegree[i] < mindeg)
{
mindeg = vDegree[i];
startvertex=i;
}
}
DFSUtil(startvertex, visited, vDegree, k);
// If Graph is disconnected.
for (int i=0; i<V; i++)
if (visited[i] == false)
DFSUtil(i, visited, vDegree, k);
// PRINTING K CORES
cout << "K-Cores : \n";
for (int v=0; v<V; v++)
{
// Only considering those vertices which have degree
// >= K after BFS
if (vDegree[v] >= k)
{
cout << "\n[" << v << "]";
// Traverse adjacency list of v and print only
// those adjacent which have vDegree >= k after
// BFS.
list<int>::iterator itr;
for (itr = adj[v].begin(); itr != adj[v].end(); ++itr)
if (vDegree[*itr] >= k)
cout << " -> " << *itr;
}
}
}
// Driver program to test methods of graph class
int main()
{
// Create a graph given in the above diagram
int k = 3;
Graph g1(8);
g1.addEdge(0, 3);
g1.addEdge(0, 1);
g1.addEdge(0, 2);
g1.addEdge(1, 4);
g1.addEdge(2, 3);
g1.addEdge(2, 4);
g1.addEdge(2, 5);
g1.addEdge(2, 6);
g1.addEdge(3, 6);
g1.addEdge(4, 5);
g1.addEdge(4, 6);
g1.addEdge(5, 6);
g1.printKCores(k);
cout << endl << endl;
Graph g2(13);
g2.addEdge(0, 1);
g2.addEdge(0, 2);
g2.addEdge(0, 3);
g2.addEdge(1, 4);
g2.addEdge(1, 5);
g2.addEdge(1, 6);
g2.addEdge(2, 7);
g2.addEdge(2, 8);
g2.addEdge(2, 9);
g2.addEdge(3, 10);
g2.addEdge(3, 11);
g2.addEdge(3, 12);
g2.printKCores(k);
return 0;
}
Ly8gQysrIHByb2dyYW0gdG8gZmluZCBLLUNvcmVzIG9mIGEgZ3JhcGgKI2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCi8vIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIHVuZGlyZWN0ZWQgZ3JhcGggdXNpbmcgYWRqYWNlbmN5Ci8vIGxpc3QgcmVwcmVzZW50YXRpb24KY2xhc3MgR3JhcGgKewoJaW50IFY7IC8vIE5vLiBvZiB2ZXJ0aWNlcwoKCS8vIFBvaW50ZXIgdG8gYW4gYXJyYXkgY29udGFpbmluZyBhZGphY2VuY3kgbGlzdHMKCWxpc3Q8aW50PiAqYWRqOwpwdWJsaWM6CglHcmFwaChpbnQgVik7IC8vIENvbnN0cnVjdG9yCgoJLy8gZnVuY3Rpb24gdG8gYWRkIGFuIGVkZ2UgdG8gZ3JhcGgKCXZvaWQgYWRkRWRnZShpbnQgdSwgaW50IHYpOwoKCS8vIEEgcmVjdXJzaXZlIGZ1bmN0aW9uIHRvIHByaW50IERGUyBzdGFydGluZyBmcm9tIHYKCWJvb2wgREZTVXRpbChpbnQsIHZlY3Rvcjxib29sPiAmLCB2ZWN0b3I8aW50PiAmLCBpbnQgayk7CgoJLy8gcHJpbnRzIGstQ29yZXMgb2YgZ2l2ZW4gZ3JhcGgKCXZvaWQgcHJpbnRLQ29yZXMoaW50IGspOwp9OwoKLy8gQSByZWN1cnNpdmUgZnVuY3Rpb24gdG8gcHJpbnQgREZTIHN0YXJ0aW5nIGZyb20gdi4KLy8gSXQgcmV0dXJucyB0cnVlIGlmIGRlZ3JlZSBvZiB2IGFmdGVyIHByb2Nlc3NpbmcgaXMgbGVzcwovLyB0aGFuIGsgZWxzZSBmYWxzZQovLyBJdCBhbHNvIHVwZGF0ZXMgZGVncmVlIG9mIGFkamFjZW50IGlmIGRlZ3JlZSBvZiB2Ci8vIGlzIGxlc3MgdGhhbiBrLiBBbmQgaWYgZGVncmVlIG9mIGEgcHJvY2Vzc2VkIGFkamFjZW50Ci8vIGJlY29tZXMgbGVzcyB0aGFuIGssIHRoZW4gaXQgcmVkdWNlcyBvZiBkZWdyZWUgb2YgdiBhbHNvLApib29sIEdyYXBoOjpERlNVdGlsKGludCB2LCB2ZWN0b3I8Ym9vbD4gJnZpc2l0ZWQsCgkJCQkJdmVjdG9yPGludD4gJnZEZWdyZWUsIGludCBrKQp7CgkvLyBNYXJrIHRoZSBjdXJyZW50IG5vZGUgYXMgdmlzaXRlZCBhbmQgcHJpbnQgaXQKCXZpc2l0ZWRbdl0gPSB0cnVlOwoJCgljb3V0PDx2PDwiIGRlZ3JlZTogIjw8dkRlZ3JlZVt2XTw8ZW5kbDsKCgkvLyBSZWN1ciBmb3IgYWxsIHRoZSB2ZXJ0aWNlcyBhZGphY2VudCB0byB0aGlzIHZlcnRleAoJbGlzdDxpbnQ+OjppdGVyYXRvciBpOwoJZm9yIChpID0gYWRqW3ZdLmJlZ2luKCk7IGkgIT0gYWRqW3ZdLmVuZCgpOyArK2kpCgl7CgkJLy8gZGVncmVlIG9mIHYgaXMgbGVzcyB0aGFuIGssIHRoZW4gZGVncmVlIG9mIGFkamFjZW50CgkJLy8gbXVzdCBiZSByZWR1Y2VkCgkJaWYgKHZEZWdyZWVbdl0gPCBrKXsKCQkJdkRlZ3JlZVsqaV0tLTsKCQkJY291dDw8Kmk8PCIgaW5zaWRlOiAiPDx2PDwiIGRlZ3JlZTogIjw8dkRlZ3JlZVsqaV08PGVuZGw7CgkJfQoKCQkvLyBJZiBhZGphY2VudCBpcyBub3QgcHJvY2Vzc2VkLCBwcm9jZXNzIGl0CgkJaWYgKCF2aXNpdGVkWyppXSkKCQl7CgkJCS8vIElmIGRlZ3JlZSBvZiBhZGphY2VudCBhZnRlciBwcm9jZXNzaW5nIGJlY29tZXMKCQkJLy8gbGVzcyB0aGFuIGssIHRoZW4gcmVkdWNlIGRlZ3JlZSBvZiB2IGFsc28uCgkJCURGU1V0aWwoKmksIHZpc2l0ZWQsIHZEZWdyZWUsIGspOwoJCX0KCX0KCgkvLyBSZXR1cm4gdHJ1ZSBpZiBkZWdyZWUgb2YgdiBpcyBsZXNzIHRoYW4gawoJcmV0dXJuICh2RGVncmVlW3ZdIDwgayk7Cn0KCkdyYXBoOjpHcmFwaChpbnQgVikKewoJdGhpcy0+ViA9IFY7CglhZGogPSBuZXcgbGlzdDxpbnQ+W1ZdOwp9Cgp2b2lkIEdyYXBoOjphZGRFZGdlKGludCB1LCBpbnQgdikKewoJYWRqW3VdLnB1c2hfYmFjayh2KTsKCWFkalt2XS5wdXNoX2JhY2sodSk7Cn0KCi8vIFByaW50cyBrIGNvcmVzIG9mIGFuIHVuZGlyZWN0ZWQgZ3JhcGgKdm9pZCBHcmFwaDo6cHJpbnRLQ29yZXMoaW50IGspCnsKCS8vIElOSVRJQUxJWkFUSU9OCgkvLyBNYXJrIGFsbCB0aGUgdmVydGljZXMgYXMgbm90IHZpc2l0ZWQgYW5kIG5vdAoJLy8gcHJvY2Vzc2VkLgoJdmVjdG9yPGJvb2w+IHZpc2l0ZWQoViwgZmFsc2UpOwoJdmVjdG9yPGJvb2w+IHByb2Nlc3NlZChWLCBmYWxzZSk7CgoJaW50IG1pbmRlZyA9IElOVF9NQVg7CglpbnQgc3RhcnR2ZXJ0ZXg7CgoJLy8gU3RvcmUgZGVncmVlcyBvZiBhbGwgdmVydGljZXMKCXZlY3RvcjxpbnQ+IHZEZWdyZWUoVik7Cglmb3IgKGludCBpPTA7IGk8VjsgaSsrKQoJewoJCXZEZWdyZWVbaV0gPSBhZGpbaV0uc2l6ZSgpOwoKCQlpZiAodkRlZ3JlZVtpXSA8IG1pbmRlZykKCQl7CgkJCW1pbmRlZyA9IHZEZWdyZWVbaV07CgkJCXN0YXJ0dmVydGV4PWk7CgkJfQoJfQoJCgoJREZTVXRpbChzdGFydHZlcnRleCwgdmlzaXRlZCwgdkRlZ3JlZSwgayk7CgoJLy8gSWYgR3JhcGggaXMgZGlzY29ubmVjdGVkLgoJZm9yIChpbnQgaT0wOyBpPFY7IGkrKykKCQlpZiAodmlzaXRlZFtpXSA9PSBmYWxzZSkKCQkJREZTVXRpbChpLCB2aXNpdGVkLCB2RGVncmVlLCBrKTsKCgkvLyBQUklOVElORyBLIENPUkVTCgljb3V0IDw8ICJLLUNvcmVzIDogXG4iOwoJZm9yIChpbnQgdj0wOyB2PFY7IHYrKykKCXsKCQkvLyBPbmx5IGNvbnNpZGVyaW5nIHRob3NlIHZlcnRpY2VzIHdoaWNoIGhhdmUgZGVncmVlCgkJLy8gPj0gSyBhZnRlciBCRlMKCQlpZiAodkRlZ3JlZVt2XSA+PSBrKQoJCXsKCQkJY291dCA8PCAiXG5bIiA8PCB2IDw8ICJdIjsKCgkJCS8vIFRyYXZlcnNlIGFkamFjZW5jeSBsaXN0IG9mIHYgYW5kIHByaW50IG9ubHkKCQkJLy8gdGhvc2UgYWRqYWNlbnQgd2hpY2ggaGF2ZSB2RGVncmVlID49IGsgYWZ0ZXIKCQkJLy8gQkZTLgoJCQlsaXN0PGludD46Oml0ZXJhdG9yIGl0cjsKCQkJZm9yIChpdHIgPSBhZGpbdl0uYmVnaW4oKTsgaXRyICE9IGFkalt2XS5lbmQoKTsgKytpdHIpCgkJCQlpZiAodkRlZ3JlZVsqaXRyXSA+PSBrKQoJCQkJCWNvdXQgPDwgIiAtPiAiIDw8ICppdHI7CgkJfQoJfQp9CgovLyBEcml2ZXIgcHJvZ3JhbSB0byB0ZXN0IG1ldGhvZHMgb2YgZ3JhcGggY2xhc3MKaW50IG1haW4oKQp7CgkvLyBDcmVhdGUgYSBncmFwaCBnaXZlbiBpbiB0aGUgYWJvdmUgZGlhZ3JhbQoJaW50IGsgPSAzOwoJR3JhcGggZzEoOCk7CglnMS5hZGRFZGdlKDAsIDMpOwoJZzEuYWRkRWRnZSgwLCAxKTsKCWcxLmFkZEVkZ2UoMCwgMik7CglnMS5hZGRFZGdlKDEsIDQpOwoJZzEuYWRkRWRnZSgyLCAzKTsKCWcxLmFkZEVkZ2UoMiwgNCk7CglnMS5hZGRFZGdlKDIsIDUpOwoJZzEuYWRkRWRnZSgyLCA2KTsKCWcxLmFkZEVkZ2UoMywgNik7CglnMS5hZGRFZGdlKDQsIDUpOwoJZzEuYWRkRWRnZSg0LCA2KTsKCWcxLmFkZEVkZ2UoNSwgNik7CglnMS5wcmludEtDb3JlcyhrKTsKCgljb3V0IDw8IGVuZGwgPDwgZW5kbDsKCglHcmFwaCBnMigxMyk7CglnMi5hZGRFZGdlKDAsIDEpOwoJZzIuYWRkRWRnZSgwLCAyKTsKCWcyLmFkZEVkZ2UoMCwgMyk7CglnMi5hZGRFZGdlKDEsIDQpOwoJZzIuYWRkRWRnZSgxLCA1KTsKCWcyLmFkZEVkZ2UoMSwgNik7CglnMi5hZGRFZGdlKDIsIDcpOwoJZzIuYWRkRWRnZSgyLCA4KTsKCWcyLmFkZEVkZ2UoMiwgOSk7CglnMi5hZGRFZGdlKDMsIDEwKTsKCWcyLmFkZEVkZ2UoMywgMTEpOwoJZzIuYWRkRWRnZSgzLCAxMik7CglnMi5wcmludEtDb3JlcyhrKTsKCglyZXR1cm4gMDsKfQo=