用于 SPOJ 底部的强连接组件
strongly connected components for spoj's BOTTOM
我正在尝试解决http://www.spoj.com/problems/BOTTOM/
以下是我正在遵循的步骤:
1) 使用 Kosaraju 算法找到强连接组件。2) 考虑强连接组件。考虑一个边缘 u。现在考虑从你到某个顶点 v 的所有边。如果 v 位于其他 SCC 中,请消除整个强连接组件。否则包括解决方案中的所有元素。
但是,我不断得到WA。请帮忙。
这是我的代码:
struct Graph{
int V;
vector<int> *adj;
vector<int> *auxiliary;
vector<vector<int> > components;
Graph(int _V)
{
V=_V;
adj=new vector<int>[V+1];
auxiliary=new vector<int>[V+1];
}
void addEdge(int u, int v)
{
adj[u].push_back(v);
auxiliary[v].push_back(u);
}
void DFS(int u, bool *visited,stack<int> &nodes)
{
visited[u]=true;
int t;
stack<int> state;
bool present;
state.push(u);
while(!state.empty())
{
t=state.top();
visited[t]=true;
present=false;
for(vector<int>::iterator it=adj[t].begin();it!=adj[t].end();it++)
{
if(!visited[*it])
{
visited[*it]=true;
state.push(*it);
present=true;
}
}
if(!present)
{
nodes.push(state.top());
state.pop();
}
}
}
void DFSutil(int u,bool *visited,set<int> &members)
{
visited[u]=true;
stack<int> state;
int t;
bool present;
state.push(u);
while(!state.empty())
{
t=state.top();
present=false;
for(vector<int>::iterator it=auxiliary[t].begin();it!=auxiliary[t].end();it++)
{
if(!visited[*it])
{
visited[*it]=true;
present=true;
state.push(*it);
}
}
if(!present)
{
members.insert(state.top());
state.pop();
}
}
}
void kosaraju()
{
bool visited[V+1];
memset(visited,false,sizeof(visited));
stack<int> nodes;
int i,t;
//store the nodes, 1st DFS
for(i=1;i<=V;i++)
{
if(!visited[i])
DFS(i,visited,nodes);
}
//run DFS on the auxiliary(transposed) graph
set<int> members;
vector<int> answers;
memset(visited,false,sizeof(visited));
while(!nodes.empty())
{
t=nodes.top();
members.clear();
if(!visited[t])
{
DFSutil(t,visited,members);
set<int>::iterator it;
for(it=members.begin();it!=members.end();it++)
{
vector<int>::iterator itt;
for(itt=adj[*it].begin();itt!=adj[*it].end();itt++)
{
if(!present(members,*itt))
break;
}
if(itt!=adj[*it].end())
break;
}
if(it==members.end())
{
for(it=members.begin();it!=members.end();it++)
answers.pb(*it);
}
}
nodes.pop();
}
sort(answers.begin(),answers.end());
tr(answers,itt)
printf("%d ",*itt);
printf("n");
}
};
乍一看,看起来深度优先搜索(假设DFS应该是深度优先)实际上可能不是深度优先,而是广度优先搜索,因为它会立即将所有未访问的邻居添加到搜索队列中。 我认为您可能需要添加一个中断语句:
for(vector<int>::iterator it=adj[t].begin();it!=adj[t].end();it++)
{
if(!visited[*it])
{
visited[*it]=true;
state.push(*it);
present=true;
-----------> break;
}
}
在评论中,sudeepdino008 正确地指出 DFS 可以通过堆栈实现,但在这种情况下,我认为在从堆栈中删除顶点之前不应将其标记为已访问:
for(vector<int>::iterator it=adj[t].begin();it!=adj[t].end();it++)
{
if(!visited[*it])
{
----------> //visited[*it]=true;
state.push(*it);
present=true;
}
}
问题是:考虑一个简单的图表
1->2
1->3
3->2
使用原始算法,顶点将按(3,2,1)
顺序而不是(2,3,1)
添加到nodes
。 这意味着,在算法的第二部分,当执行向后BFS时,2
将在3
之前被选中,并且算法将错误地输出(2,3)
是强连接组件。
相关文章:
- 到连接组件算法的问题(递归)
- 使用 bfs 解决连接组件问题时得到错误的答案
- 将无向连接图分解为两个组件
- 连接的组件程序产生不正确的输出
- 查找每个连接组件区域的邻域
- 根据现有的标签(而不是二进制图像)查找使用 OpenCV 连接的组件
- 如何在OpenCV中对连接组件进行分割
- OpenCV 3.4.0 中带有 cuda 的连接组件(在 GPU 上)
- 在一个DFS中查找Di-Graph中的强烈连接组件
- OpenCV 中的连接组件
- 使用带有笛卡尔点的升压连接组件
- C++ 中无向图中的连接组件
- 用于 SPOJ 底部的强连接组件
- OpenCV如何在二进制图像中查找连接组件的列表
- 连接组件算法输出
- 定义强连接组件
- C++-如何增加堆栈大小以允许Kosaraju算法进行更多递归以计算强连接组件
- DFS:如何在c++中表示连接组件的节点
- 带有STL c++ bug的强连接组件
- 图形连接和连接组件