ファイバーネットワークスケルトンを行うための演習があります。各ノードはIPアドレスで表されます。入力時に、ネットワークを構築するコマンド(B)を取得し、次に、あるノードと別のノードの間に接続があるかどうかを確認するコマンド(T)を取得します。
すべてのTコマンドについて、私は答えなければなりません:はいまたはいいえ。したがって、この例では次のようになります。YNYYN.良い結果が得られましたが、実行時間でソリューションが失敗します-ここで確認します:https://pl.spoj.com/problems/TFIBRE/
私のコード(編集済み):
#include <iostream>
#include <string>
#include <unordered_map>
#include <list>
#include <set>
#include <arpa/inet.h>
using namespace std;
class Graph
{
std::unordered_map<uint32_t, bool> visited;
std::unordered_map<uint32_t, set<uint32_t>> adj;
bool DFSUtil(const uint32_t& v, const uint32_t&, std::unordered_map<uint32_t, bool>& visited);
public:
Graph(): visited{}, adj{}
{}
void addEdge(const uint32_t& v, const uint32_t& w);
bool DFS(const uint32_t& v, const uint32_t& el);
};
void Graph::addEdge(const uint32_t& v, const uint32_t& w)
{
adj[v].insert(w);
adj[w].insert(v);
}
bool Graph::DFSUtil(const uint32_t& v, const uint32_t& el, std::unordered_map<uint32_t, bool>& visited)
{
if (v == el){
return true;
}
visited[v] = true;
set<uint32_t>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
if (!visited[*i]){
if(DFSUtil(*i, el, visited))
return true;
else
continue;
}
return false;
}
bool Graph::DFS(const uint32_t& v, const uint32_t& el)
{
visited.clear();
for (std::pair<uint32_t, set<uint32_t>> element : adj)
visited[element.first] = false;
return DFSUtil(v, el, visited);
}
int main()
{
Graph g;
char command;
char addr1[16];
char addr2[16];
in_addr ip1;
in_addr ip2;
while (scanf("%c %s %s ", &command, addr1, addr2) == 3)
{
inet_aton(addr1, &ip1);
inet_aton(addr2, &ip2);
if (command == 'B')
g.addEdge(ip1.s_addr, ip2.s_addr);
else
cout << (g.DFS(ip1.s_addr, ip2.s_addr) ? "T\n" : "N\n");
}
return 0;
}
検索に最も時間がかかります。これを改善するために何ができますか?たぶん私はstlコンテナを使うべきではありませんか?しかし、それでは何を使うのでしょうか?
リンクが双方向であり、距離に制限がない場合は、https://en.wikipedia.org/wiki/Disjoint-set_data_structure(別名Union-Find)を使用してみてください。リンクが表示されたら、リンクの両端を所有するセットをマージします。接続をテストするには、両端が同じセットにマージされているかどうかを確認します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加