-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGraph.cpp
More file actions
82 lines (78 loc) · 2.29 KB
/
Copy pathGraph.cpp
File metadata and controls
82 lines (78 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Graph.cpp
#include "Graph.h"
#include <fstream>
#include <queue>
#include <algorithm>
// Load graph from a file of edges (assumes 0-based vertices).
void Graph::loadFromFile(const std::string& filename) {
std::ifstream in(filename);
int u,v;
int maxv = 0;
std::vector<std::pair<int,int>> eds;
while(in >> u >> v) {
if(u==v) continue;
eds.emplace_back(u,v);
eds.emplace_back(v,u);
maxv = std::max({maxv,u,v});
}
adj.assign(maxv+1, {});
for(auto &e: eds) {
adj[e.first].insert(e.second);
}
}
// Remove an edge (u,v) and (v,u)
void Graph::removeEdge(int u, int v) {
adj[u].erase(v);
adj[v].erase(u);
}
// Return all edges (u<v) in the graph.
std::vector<Edge> Graph::edges() const {
std::vector<Edge> list;
for(int u=0; u<adj.size(); u++) {
for(int v: adj[u]) {
if(u < v) list.emplace_back(u,v);
}
}
return list;
}
// Compute the maximal t-truss >= k_min. Returns (T,t), where T is the max-truss subgraph and t its trussness.
std::pair<Graph,int> Graph::maxTruss(int k_min) const {
// Copy the graph to peel.
Graph H = *this;
int t = k_min;
Graph lastNonEmpty;
int last_t = k_min-1;
// Peel for k = k_min, k_min+1, ... until empty.
for(int k = k_min; ; k++) {
bool changed = true;
// Iteratively remove edges with support < k-2
while(changed) {
changed = false;
std::vector<Edge> toRemove;
// Compute support of each edge in H
for(auto &e : H.edges()) {
int u=e.first, v=e.second;
// count common neighbors
int supp = 0;
for(int nei : H.adj[u]) if(H.adj[v].count(nei)) supp++;
if(supp < k-2) {
toRemove.emplace_back(u,v);
}
}
if(!toRemove.empty()) {
changed = true;
for(auto &e : toRemove) {
H.removeEdge(e.first, e.second);
}
}
}
if(H.edges().empty()) {
// No edges remain at this k; break
break;
}
// Save this as last non-empty and continue
lastNonEmpty = H;
last_t = k;
}
return { lastNonEmpty, last_t };
}