检测一个由链表表示的图中3个相邻顶点的循环
Detect a cycle of 3 adjacent vertices in a graph represented by a linked list
给定一个无向图,其边数多于顶点数,并用相邻顶点的链表表示。如何检测是否存在3个相邻顶点的循环,时间复杂度是多少?
示例图:
1->2->5
2->3->1->4
3->2->4
4->2->5->3
5->1->4
存在3个相邻顶点的循环2->3->4->2
这个问题可以解决,使用算法深度优先搜索:
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
const int maximumSize=40;
vector<vector<int>> visited(maximumSize, vector<int>(maximumSize, 0));
vector<int> graph[maximumSize], closedContour, temporary;
int vertices, edges;
set<vector<int>> contours;
void showContentSetVector(set<vector<int>> input)
{
for(auto iterator=input.begin(); iterator!=input.end(); ++iterator)
{
for(auto item : *iterator)
{
cout<<item<<", ";
}
cout<<endl;
}
return;
}
bool compare(int i,int j)
{
return (i<j);
}
void createGraph()
{
cin>>vertices>>edges;
int vertex0, vertex1;
for(int i=1; i<=edges; ++i)
{
cin>>vertex0>>vertex1;
graph[vertex0].push_back(vertex1);
graph[vertex1].push_back(vertex0);
}
return;
}
void depthFirstSearch(int initial, int current, int previous)
{
if(visited[initial][current]==1)
{
for(int i=0; i<temporary.size(); ++i)
{
if(temporary[i]==current)
{
for(int j=i; j<temporary.size(); ++j)
{
closedContour.push_back(temporary[j]);
}
}
}
sort(closedContour.begin(), closedContour.end(), compare);
contours.insert(closedContour);
closedContour.clear();
return;
}
visited[initial][current]=1;
temporary.push_back(current);
for(int next : graph[current])
{
if(next==previous)
{
continue;
}
depthFirstSearch(initial, next, current);
}
temporary.pop_back();
return;
}
void solve()
{
createGraph();
for(int vertex=1; vertex<=vertices; ++vertex)
{
temporary.clear();
depthFirstSearch(vertex, vertex, -1);
}
cout<<"contours <- ";
showContentSetVector(contours);
return;
}
int main()
{
solve();
return 0;
}
结果如下:
contours <-
1: 1, 2, 3, 4, 5,
2: 1, 2, 4, 5,
3: 2, 3, 4,
正如您在提供的循环(闭合轮廓)中看到的那样,您在问题中提到了该轮廓,由 3 个相邻顶点组成:vertices={2, 3, 4}
.
因为您提到您的 图是无向的 我认为您的示例图必须如下所示:
1:[2, 5],
2:[1, 3, 4],
3:[2, 4],
4:[2, 3, 5],
5:[1, 4].
给定一个无向图,其边数多于顶点数,并用相邻顶点的链表表示。如何检测是否存在3个相邻顶点的循环,时间复杂度是多少?
示例图:
1->2->5
2->3->1->4
3->2->4
4->2->5->3
5->1->4
存在3个相邻顶点的循环2->3->4->2
这个问题可以解决,使用算法深度优先搜索:
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
const int maximumSize=40;
vector<vector<int>> visited(maximumSize, vector<int>(maximumSize, 0));
vector<int> graph[maximumSize], closedContour, temporary;
int vertices, edges;
set<vector<int>> contours;
void showContentSetVector(set<vector<int>> input)
{
for(auto iterator=input.begin(); iterator!=input.end(); ++iterator)
{
for(auto item : *iterator)
{
cout<<item<<", ";
}
cout<<endl;
}
return;
}
bool compare(int i,int j)
{
return (i<j);
}
void createGraph()
{
cin>>vertices>>edges;
int vertex0, vertex1;
for(int i=1; i<=edges; ++i)
{
cin>>vertex0>>vertex1;
graph[vertex0].push_back(vertex1);
graph[vertex1].push_back(vertex0);
}
return;
}
void depthFirstSearch(int initial, int current, int previous)
{
if(visited[initial][current]==1)
{
for(int i=0; i<temporary.size(); ++i)
{
if(temporary[i]==current)
{
for(int j=i; j<temporary.size(); ++j)
{
closedContour.push_back(temporary[j]);
}
}
}
sort(closedContour.begin(), closedContour.end(), compare);
contours.insert(closedContour);
closedContour.clear();
return;
}
visited[initial][current]=1;
temporary.push_back(current);
for(int next : graph[current])
{
if(next==previous)
{
continue;
}
depthFirstSearch(initial, next, current);
}
temporary.pop_back();
return;
}
void solve()
{
createGraph();
for(int vertex=1; vertex<=vertices; ++vertex)
{
temporary.clear();
depthFirstSearch(vertex, vertex, -1);
}
cout<<"contours <- ";
showContentSetVector(contours);
return;
}
int main()
{
solve();
return 0;
}
结果如下:
contours <-
1: 1, 2, 3, 4, 5,
2: 1, 2, 4, 5,
3: 2, 3, 4,
正如您在提供的循环(闭合轮廓)中看到的那样,您在问题中提到了该轮廓,由 3 个相邻顶点组成:vertices={2, 3, 4}
.
因为您提到您的 图是无向的 我认为您的示例图必须如下所示:
1:[2, 5],
2:[1, 3, 4],
3:[2, 4],
4:[2, 3, 5],
5:[1, 4].