给出DI图。检查所有节点对

时间:2015-08-22 20:38:38

标签: c++ data-structures graph

如果我有Di-Graph。如何检查该图的所有节点对(u,v)是否相关? 关系表示[u,v]或[v,u]之间存在关联。

这是一个例子:
在此图像中,最左边的图形具有所有对之间的关​​系。右边没有;

Example

为了解决这个问题,我尝试了原始给定图表及其反转图表中的BFS。 当且仅当使用两个bfs访问所有节点时,我们才有相关的图形。 否则图表没有相关性。

#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");
}

但这种解决方案在30%的测试用例中是错误的;这是一个竞赛问题,我无法访问输入=(

我做错了什么?

输入说明

  

第一行有两个整数 N M (1≤N,M≤100000),下一个 M 行有两个整数 U V (1≤U,V≤N)。

     

示例输入1
  3 3
  1 3
  2 3
  3 1

     

示例输入2
  3 2
  1 3
  2 3

     

示例输出1
  所有配对相关

     

示例输出2
  所有配对都不相关

1 个答案:

答案 0 :(得分:2)

因此,可以使用任何图形遍历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.

首先检查图表是否连接强烈,如果是,则绝对是图表连接的图表,如果没有继续如下:

从任何源顶点S开始遍历图形,其中S必须同时具有indegree和outdegree> 0,如果我们没有这种类型的任何顶点,则图形未连接(原因在最后)。

现在将所有被访问的顶点标记为集合S1的元素。

然后反转图形并再次从相同的源顶点S开始图遍历。

再次将所有被访问的顶点标记为集合S2的元素。

当且仅当

时才连接图表
S1 U S2 = V

矛盾证明。

让我们假设上述算法是错误的,并说即使

,图也是连接的
S1 U S2 is proper subset of V.

但是如果S1 U 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.

考虑图表:enter image description here

假设我们从X开始第一次遍历,然后我们有:

S1={X,Y,e}

S2={X}

并且显然S1 U S2 = V,但是没有路径对(Y,e)和这就是源顶点必须同时具有indegree和outdegree的原因&gt; 0显然X没有,实际上没有顶点满足这个条件,因此图形没有连接。