2021-1 無向圖中v到w最短路徑 與 連通子圖的個數 c++
阿新 • • 發佈:2021-01-22
最短路徑
從指定起點s做廣度優先搜尋,總能找到一條從s到v的最短路徑,O(V+E)。
標頭檔案 Paths.h
#include"Paths.h"
void findShortestPath(Graph& G, int s, int v) {
Paths pathG(G, s);//預設廣搜,下面列印最短路徑
if (pathG.hasPathto(v)) {
for (auto& w : pathG.pathTo(v)) {
if (w == s) printf_s("%2d " , s);
else
printf_s("-%2d ", w);
}
printf_s("\n");
}
else {
printf_s("s v unconnected.\n");
}
}
//test
int main() {
Graph G("data.txt");
findShortestPath(G, 11, 4);
system("pause");
return 0;
}
連通子圖的個數
對每個未標記的節點做深度優先搜尋,搜尋次數即連通子圖個數,O(V+E)。
#include"Graph.h"
void dfs(Graph&, int, vector<bool>*);
int numOfConnectedSubgraphs(Graph &G) {
int ans = 0;
vector<bool>* marked = new vector<bool>(G.V(), false);
for (int i = 0; i < G.V(); ++i) {
if (!marked->at(i)) {
dfs(G, i,marked);
++ ans;
}
}
return ans;
}
void dfs(Graph& G, int v, vector<bool>* marked) {
marked->at(v) = true;
for (auto& next : G.adj(v)) {
if(!marked->at(next))
dfs(G, next,marked);
}
}
int main() {
Graph G("data.txt");
cout << numOfConnectedSubgraphs(G) << endl;
system("pause");
return 0;
}
連通分量的API 及其實現
標頭檔案見 Graph.h
cc.h
#pragma once
#include"Graph.h"
#define out(x) cout<<x<<" "
#define hh printf_s("\n")
//聯通分量
class CC
{
public:
CC(Graph& G);
bool connected(int v, int w) { return m_id->at(v) == (*m_id)[w]; }
int count() { return m_count; }
int id(int v) { return m_id->at(v); }
private:
vector<int>* m_visited = nullptr;
vector<int>* m_id = nullptr;//屬於哪一個聯通分量: 0 ~ m_count-1
int m_count = 0;
void dfs(Graph& G, int start);
};
void testCC();
cc.cpp
#include "CC.h"
CC::CC(Graph& G)
{
int n = G.V();
m_visited = new vector<int>(n, 0);
m_id = new vector<int>(n, -1);
for (int s = 0; s < n; ++s) {
if (!m_visited->at(s)) {
dfs(G, s);
m_count++;
}
}
}
void CC::dfs(Graph& G, int start)
{
m_visited->at(start) = 1;
m_id->at(start) = m_count;//當前深度搜索中發現的都是同一個id
for (auto& next : G.adj(start))
{
if (!m_visited->at(next)) {
dfs(G, next);
}
}
}
void testCC()
{
Graph G("data.txt");
CC search(G);
out("0 10 connected ? ");
out((search.connected(0, 10) ? "yes" : "no")),hh;
out("0 belongs to subG_i "), out(search.id(0)), hh;
out("10 belongs to subG_i "), out(search.id(10)), hh;
out("How many ConnectedSubgraphs ? "), out(search.count()), hh;
}