C++ 给出一个DI图。检查对于所有节点对,是否存在来自(u,v)或(v,u)的路径
如果我有一个Di图。如何检查此图的所有节点对(u,v)是否相关?C++ 给出一个DI图。检查对于所有节点对,是否存在来自(u,v)或(v,u)的路径,c++,data-structures,graph,C++,Data Structures,Graph,如果我有一个Di图。如何检查此图的所有节点对(u,v)是否相关? 关系表示[u,v]或[v,u]之间存在连接 下面是一个例子: 在此图像中,最左边的图形在所有对之间具有关系。正确的一个不是 为了解决这个问题,我试着从原始的给定图和它的反向图中选择BFS。 我们有一个相关图,当且仅当所有节点都被两个BF访问时。 否则,图表就不相关了 #include <stdio.h> #include <vector> #include <queue> #include &
关系表示[u,v]或[v,u]之间存在连接 下面是一个例子:
在此图像中,最左边的图形在所有对之间具有关系。正确的一个不是 为了解决这个问题,我试着从原始的给定图和它的反向图中选择BFS。 我们有一个相关图,当且仅当所有节点都被两个BF访问时。 否则,图表就不相关了
#include <stdio.h>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vii;
void DFS(bool *vst,vii &G,int ini){
queue<int> q;
q.push(ini);
int cur;
while(!q.empty()){
cur = q.front();
q.pop();
if(vst[cur])
continue;
vst[cur] = true;
vi &adj = G[cur];
for (vi::iterator it = adj.begin(); it != adj.end(); ++it)
q.push(*it);
}
}
int main(void){
//N is the number of Nodes and M is the number of Edges
int n,m;
scanf("%d %d",&n,&m);
vii G(n+1); //graph
vii R(n+1);//reversed graph
//read and fill both graphs
for (int i = 0,u,v; i < m; ++i) {
scanf("%d %d",&u,&v);
G[u].push_back(v);
R[v].push_back(u);
}
//get some node with outdegree and indegree > 0
int S = -1;
for (int i = 1; i <= n; ++i){
if(G[i].size() > 0 && R[i].size() > 0){
S = i;
break;
}
}
bool vst1[n+1];
bool vst2[n+1];
for (int i = 1; i <= n; ++i)
vst1[i] = vst2[i] = false;
if(S != -1){
DFS(vst1, G, S);
DFS(vst2, R, S);
}
int i;
for (i = 1; i <= n; ++i){
if((vst1[i] || vst2[i]) == false){
i = -1;
break;
}
}
if(i == n+1)
puts("All pairs related");
else
puts("All pairs not-related");
}
#包括
#包括
#包括
#包括
使用名称空间std;
typedef向量vi;
病毒载体vii型;
无效DFS(bool*vst、vii&G、int ini){
队列q;
q、 推送(ini);
int cur;
而(!q.empty()){
cur=q.front();
q、 pop();
if(vst[cur])
继续;
vst[cur]=真;
vi&adj=G[cur];
对于(vi::迭代器it=adj.begin();it!=adj.end();++it)
q、 推动(*it);
}
}
内部主(空){
//N是节点数,M是边数
int n,m;
scanf(“%d%d”,&n,&m);
vii G(n+1);//图
vii R(n+1);//逆图
//阅读并填写两个图表
对于(int i=0,u,v;i0的某个节点
int S=-1;
对于(int i=1;i 0&&R[i].size()>0){
S=i;
打破
}
}
bool-vst1[n+1];
bool-vst2[n+1];
对于(inti=1;iSo),可以使用任何图遍历BFS或DFS轻松检查这一点
我假设这个定义
A directed graph is connected if for all pairs (u,v), there exists a directed path from u
to v OR there exists a directed path from v to u.
首先检查图是否强连接,如果是,则确定图是连接的,如果不是,则按以下步骤进行:
There is no path from v to S and also from S to v.
从任何源顶点S开始图遍历,其中S必须同时具有indegree和outdegree>0,如果我们没有此类类型的顶点,则图未连接(最后的原因)
现在将访问的所有顶点标记为集合S1的元素
然后反转图形,再次从相同的源顶点S开始图形遍历
再次将访问的所有顶点标记为集合S2的元素
图是连通的当且仅当
S1 U S2 = V
用矛盾来证明
让我们假设上面的算法是错误的,并且假设图是连通的,即使
S1 U S2 is proper subset of V.
但如果s1u S2是V的一个适当子集,则必须有一个顶点V,在两次遍历中都保持不变,这意味着:
There is no path from v to S and also from S to v.
因此矛盾,因此我们的初始假设是错误的,在S1 U S2是V的适当子集的情况下,图不能连通
现在取任意一对顶点(u,v)
案例1:
S1 and S2 both contained u and v, which means that there is a directed path
from u to v and also from v to u.
案例2:
u and v are in different sets,still there exists a path from u to v OR from
v to u.
案例3:
Both u and v are in same set.
考虑下图:
假设我们从X开始第一次遍历,那么我们有:
S1={X,Y,e}
S2={X}
很明显,S1 U S2=V,但对(Y,e)没有路径这就是为什么源顶点必须同时具有indegree和outdegree>0的原因,而X显然没有,而且实际上没有任何顶点满足此条件,因此图形是不连通的。如果有一些路径需要向前和向后移动的混合,该怎么办?@Felipe这是一个相当简单的算法。但我知道我已经用Java实现了它。@Sumeet你能解释一下吗?我的方法是正确的还是不能解决问题?@Sumeet我知道Java=)@Felipe你想让我解释算法还是代码,还是两者都要解释。我认为它解决不了问题=(。因为此算法检查所有图形对是否都有指向u、v和v、u的路径。我需要一个算法来检查所有图形对是否都有来自u、v或v、u的路径。@Felipe很抱歉,从未见过or,将更新我的答案。没问题。谢谢你的帮助。你不需要道歉=)我已经尝试过实现它,但仍然有相同的错误百分比;