親マップにないということは、BFSツリーのリーフであることを意味していると仮定すると、アルゴリズムは間違っています。
グラフ10個の頂点と次の無向エッジを持ってみましょう:(ルート0
で)有効BFS木の
0 1
0 4
1 2
1 3
2 3
2 6
2 7
3 8
4 5
4 6
5 9
6 7
6 8
7 8
7 9
一つは:
0 1
1 2
1 3
2 7
3 8
0 4
4 6
4 5
5 9
葉6, 7, 8, 9
あるので、この解決策3を返します。 それは間違っています。答えは4
です(3
と5
の間の距離です)。
最も遠いノードをすべて取得することは、このテストでは機能しません。
反例を探すように頼むのではなく、何百万もの小さなランダムテストケースを生成し、解決策が正しい答えを出すかどうかをチェックすることで、それを実行できます。ここで私はこのケースを生成するために使用されるコードは(それは非常に良い見ていないが、それは仕事をしていません)です:
pair<vector<int>, set<int>> bfs(int st, const vector<vector<int>>& g) {
int n = g.size();
vector<int> d(n, n);
d[st] = 0;
queue<int> q;
q.push(st);
set<int> parents;
while (!q.empty()) {
int v = q.front();
q.pop();
for (int to : g[v])
if (d[to] > d[v] + 1) {
d[to] = d[v] + 1;
q.push(to);
parents.insert(v);
}
}
return {d, parents};
}
int get_max_dist(const vector<vector<int>>& g) {
int res = 0;
for (int i = 0; i < (int)g.size(); i++) {
auto cur = bfs(i, g).first;
for (int x : cur)
cerr << x << " ";
cerr << endl;
res = max(res, *max_element(cur.begin(), cur.end()));
}
cerr << endl;
return res;
}
int get_max_dist_weird(const vector<vector<int>>& g) {
auto p = bfs(0, g);
vector<int> cand;
int n = g.size();
for (int i = 0; i < n; i++)
if (!p.second.count(i))
cand.push_back(i);
int res = 0;
for (int i : cand) {
auto cur = bfs(i, g).first;
res = max(res, *max_element(cur.begin(), cur.end()));
}
return res;
}
vector<vector<int>> rand_graph(int n) {
vector<vector<int>> g(n);
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
if (rand() & 1) {
g[i].push_back(j);
g[j].push_back(i);
}
return g;
}
int main() {
for (int i = 1;; i++) {
int n = 10;
auto g = rand_graph(n);
int correct = get_max_dist(g);
int got = get_max_dist_weird(g);
if (correct != got) {
cerr << correct << " " << got << endl;
for (int v = 0; v < n; v++)
for (int j : g[v])
if (v < j)
cerr << v << " " << j << endl;
}
assert (get_max_dist_weird(g) == get_max_dist(g));
if (i % 1000 == 0)
cerr << i << endl;
}
}
確かに、アルゴリズムは、このように正しいことを証明することはできませんが、それは非常にですそれがそうでない場合、反例を見つける可能性が高い。
問題のグラフは、重み付けされているか、重み付けされていないか、木ではありませんか? –
@JaysonBoubin無意味な、重み付けされていない、そして必ずしもツリーではないかもしれませんが、 –
**最短パス(ステップ2の角括弧内に記載されているもの)にないノード間には大きな違いがあります。 ** 1つの最短経路にないノード(実際には2つのステップが実際にやっていると思われるノード)。無向グラフの「親ノード」とは何ですか? – Dukeling