确定无向图是否为树

时间:2016-04-23 20:20:17

标签: c algorithm graph tree

我已经研究了有向图和无向图。我的方法是使用DFS算法。我知道当visitedM[iVertices]true或节点被访问两次时,这意味着它不是树。我还确定图形是否是树,我使用以下定理。

Theorem: Any connected graph with n vertices and n-1 edges is a tree

我的代码是通过从文件中读取顶点数和边数来初始化的,如下所示

6 7
1 2
1 5
1 6
2 5

如您所见,每条边都列在具有源顶点和目标顶点的一行上。顶点从1开始。边缘是未定向的并且将是 从最小的顶点id开始,在文件上列出。例如,对于边2-5和5-2,文件将只有2-5。

我的问题是我不知道是否应该分配节点内存,如何将节点插入图中,如何从DFS代码中告诉我不是树。我还将void dfs作为int函数返回访问顶点的计数。 int dft(grapg *g, int iV, int VisitedM[])。该函数类似于我的void DFS,但它返回0 如果visitedM[iV]visitedM[iV] = TRUE,则返回iCount。 我还假设我的数据结构很混乱。

#define MAX_VERTICES 100
typedef struct EdgeNode
{
    int y;
    int w;          //weight
    int iVertex     //susbcript in vertexM for TO Vertex
    struct EdgeNode *pNextEdge;
}EdgeNode;

typedef struct Vertex
{
    char szLabel[100 +1 ];
    EdgeNode *successorList;
}Vertex;

typedef struct
{
    int iNumVertices;
    int iNumEdges;
    int iDirected;
    Vertex vertexM[MAX_VERTICES +1];

    int iParent[MAX_VERTICES + 1];
    int iVisitedM[MAX_VERTICES + 1];

    int degree[MAX_VERTICES + 1];
    EdgeNode *edge[MAX_VERTICES +1];
}GraphImp;
typedef GraphImp *Graph;


    int main(int argc, char *argv[])
    {
        FILE *pFile;
        Graph graph;
        char szInputBuffer[100];
        int numEdges, numVertices;
        pFile = fopen("a.txt","r");

        if( pFile == NULL)
        {
            printf("FILE DOES NOT EXIST \n");
            return;
        }
        //reads file until EOF
        while(fscanf(pFile, "%d%d", &graph.iVertices, &graph.iEdges) != EOF)
        {
            //printf is to track the input from file
            printf("num of vertices: %d \n num of edeges: %d \n",graph.iVertices, graph.iEdges);
        }

        fclose(pFile);
    }
            void dft(Graph *g, int iV, int visitedM[])
        {
            EdgeNode *e;
            if(visitedM[iV])
                return;
            for( e = g->vertexM[iV].sucessorList; e!= NULL; e = e->pNextEdge)
            {
                dft(g, e->iVertex, visitedM);
            }
        }

1 个答案:

答案 0 :(得分:4)

让我给你一个稍微不同的解决问题的方法。

给定问题{{6,7}, {1,2}, {1,5}, {1,6}, {2,5}}中的边缘集合,有5个顶点{1,2,5,6,7}和5个边。我们立即得出结论,图不能是树,因为根据定理,具有5个顶点的图必须有4个边。

要使问题稍微困难一点,请删除其中一条边,留下{{6,7}, {1,2}, {1,6}, {2,5}}。现在我们有正确的边数,所以根据定理,我们只需要证明图是连接的。这可以通过着色图表来完成。

要为图表着色,请实施这三个规则

  • 如果边连接两个未着色的顶点,则为这些顶点提供一种新颜色
  • 如果边缘将彩色顶点连接到未着色的顶点,则将颜色指定给未着色的顶点
  • 如果边连接两个不同颜色的顶点,则将这些颜色合并为单一颜色

如果每个顶点都以相同的颜色结束,那么图表就会连接起来。

下表显示了在处理每条边时,颜色分配如何随时间变化。

       |     color assignments 
vertex | start {6,7} {1,2} {1,6} {2,5} 
-------+-------------------------------
  1    |   0     0     2     1     1
  2    |   0     0     2     1     1
  3    |   0     0     0     0     0
  4    |   0     0     0     0     0
  5    |   0     0     0     0     1
  6    |   0     1     1     1     1
  7    |   0     1     1     1     1

在开始时,所有顶点都是未着色的,由数字0表示。第一条边{6,7}为顶点6和7指定一种新颜色。第二条边{1,2}指定一种新颜色第一条边{1,6}连接具有不同颜色的顶点,因此所有颜色为2的顶点都变为颜色1.最后一条边{2,5}连接一个彩色顶点和一个未着色的顶点,所以将颜色1分配给顶点5。

处理完所有边后,所有彩色顶点都具有相同的颜色,因此图形已连接。此外,边缘的数量比顶点的数量少一个。因此,图表是一棵树。