# 读图函数 defread_graph(): first_line = input().strip() n, m = map(int, first_line.split()) graph = defaultdict(set) for _ inrange(m): u, v = input().strip().split() graph[u].add(v) graph[v].add(u) return graph
defbron_kerbosch_pivot(graph): defbk(R, P, X): # 如果P和X都是空的,说明R这个团已经是极大团了 ifnot P andnot X: cliques.append(R) return # 选择轴顶点:从P∪X中选邻居最多的顶点 pivot = max(P.union(X), key = lambda v: len(graph[v])) # 只需要处理P中不属于轴顶点邻居的顶点 for v in P.difference(graph[pivot]): neighbors = graph[v] bk(R | {v}, P & neighbors, X & neighbors) P.remove(v) X.add(v) cliques = [] bk(set(), set(graph.keys()), set()) return cliques
if __name__ == "__main__": graph = read_graph() for node in graph: print(f"{node}: {graph[node]}")
intmain() { cin >> n >> m; for(int x = 1; x <= m; x++) { int u, v; cin >> u >> v; G[u].push_back(v); G[v].push_back(u); } for(int x = 1; x <= n; x++) sort(G[x].begin(), G[x].end());
vector <int> R, P, X; for(int x = 1; x <= n; x++) P.push_back(x);
BK(R, P, X);
for(int v : maxClique) cout << v << " "; cout << endl; return0; }
Efficient Maximum s-Bundle Search via Local Vertex Connectivity
标题大意:基于局部顶点联通性的高效最大s-Bundle搜索
概念
s-Bundle:
The 𝑠-bundle, as a cohesive subgraph model which relaxes the clique, remains connected whenever fewer than 𝑛 − 𝑠 vertices are removed, where 𝑛 is the number of vertices inside.
An effective branch-and-bound algorithm for the maximum s-bundle problem
Existing examples of relaxed cliques include s-plex , s-defective clique , and quasi-clique and s-club which are defined by relaxing the vertex degree, edge number, edge density, and pairwise distance of vertices, respectively.
A vertex cut of a connected graph G is a subset of vertices in which, upon removal of these vertices and their incident edges from G, the remaining graph becomes a disconnected or trivial graph (a 1-vertex graph).
while (!q.empty()) { int u = q.front(); q.pop(); for (int v : adj[u]) { if (cap[u][v] > 0 && parent[v] == -1) { parent[v] = u; if (v == t) returntrue; q.push(v); } } } returnfalse; }
// 判定集合 R 是否为 s‑bundle boolisSB(const vector<int>& R, int s) { int k = (int)R.size() - s; if (k == 0) returntrue; // k = 0 总是成立 if (k == 1){ // k = 1 只需连通 /* 尝试在 R 的诱导子图里跑一次 BFS,看能否遍历完 */ queue<int> q; unordered_set<int> inR(R.begin(),R.end()); unordered_set<int> vis; q.push(R[0]); vis.insert(R[0]);
for (int v : R) { int vin = id[v] * 2, vout = vin + 1; base[vin][vout] = 1; // 顶点容量 1 adj[vin].push_back(vout); adj[vout].push_back(vin); // 反向边 } for (int u : R) for (int v : G[u]) if (id[v] != -1) { int uout = id[u] * 2 + 1, vin = id[v] * 2; base[uout][vin] = k; adj[uout].push_back(vin); adj[vin].push_back(uout); // 反向边 }
/* ---------- 枚举所有无序点对 (u,v) ---------- */ int sz = (int)R.size(); for (int a = 0; a < sz; ++a) for (int b = a + 1; b < sz; ++b) { int u = R[a], v = R[b]; auto cap = base; // 拷贝容量
int src = id[u]*2 + 1; // u_out int dst = id[v]*2; // v_in
for (int f = 0; f < k; ++f) { // 连找 k 条路 vector<int> par(tot, -1); if (!bfs(src, dst, adj, cap, par)) returnfalse; for (int x = dst; x != src; x = par[x]) { int p = par[x]; --cap[p][x]; ++cap[x][p]; } } } returntrue; }
// 判定能否把 c 加进已知的 s‑bundle P booladdSB(const vector<int>& P, int c, int s) { vector<int> S = P; S.push_back(c); int k = (int)S.size() - s; if (k <= 1) returntrue;
int id[MAXN]; fill(id, id + MAXN, -1); int n = 0; for (int v : S) id[v] = n++; int tot = 2 * n;
for (int v : S) { int vin = id[v]*2, vout = vin+1; base[vin][vout] = (v == c ? k : 1); adj[vin].push_back(vout); adj[vout].push_back(vin); } for (int u : S) for (int v : G[u]) if (id[v] != -1) { int uout = id[u]*2+1, vin = id[v]*2; base[uout][vin] = k; adj[uout].push_back(vin); adj[vin ].push_back(uout); }
for (int i : P) { int src = id[i]*2, srcOut = src+1, dst = id[c]*2+1; auto cap = base; cap[src][srcOut] = k; // 源点容量=k
for (int f = 0; f < k; ++f) { vector<int> par(tot, -1); if (!bfs(src, dst, adj, cap, par)) returnfalse; for (int v = dst; v != src; v = par[v]) { int u = par[v]; --cap[u][v]; ++cap[v][u]; } } } returntrue; }
cin >> n >> m; for(int x = 1; x <= m; x++) { int u, v; cin >> u >> v; G[u].push_back(v); G[v].push_back(u); } for(int x = 1; x <= n; x++) sort(G[x].begin(), G[x].end());
cout << "Graph input complete!" << endl << endl;
//for(int x = 1; x <= n; x++) cout << x << ": " << G[x].size() << endl; vector <int> R, P, X; for(int x = 1; x <= n; x++) P.push_back(x);
for(int a=0;a<n;++a){ int u = S[a]; for(int v : G[u]){ int b = vidx[v]; if(b < 0) continue; // v 不在 S if(a < b){ din.addEdge(a+n, b, INF); din.addEdge(b+n, a, INF); } } }