关节点(邻接表)

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <Windows.h>

using namespace std;

#define INFINITY 65535
#define MAX_VERTEX_NUM 20  //顶点最多个数
#define LENGTH 5           //顶点字符长度
//*********************************邻接表***********************************begin
typedef char VertexType[LENGTH];
typedef struct ArcNode
{
    int adjvex;
    struct ArcNode* nextarc;
    int weight;
}ArcNode;

typedef struct VNode
{
    VertexType data;
    ArcNode *firstarc;
}VNode, AdjList[MAX_VERTEX_NUM];

typedef struct
{
    AdjList vertices;
    int vexnum;
    int arcnum;
}ALGraph;

int LocateVex(const ALGraph & g, char name[LENGTH])
{
    for (int i = 0; i < g.vexnum; i++)
    {
        if (0 == strcmp(g.vertices[i].data, name))
        {
            return i;
        }
    }
    return -1;
}

//图的建造
void CreateGraph(ALGraph &g)
{
    ifstream fcin(_T("articul.txt"));
    fcin>>g.vexnum;
    
    for (int i = 0; i < g.vexnum; i++)
    {
        fcin>>g.vertices[i].data;
        g.vertices[i].firstarc = NULL;
    }
    fcin>>g.arcnum;
    char arcHead[LENGTH];
    char arcTail[LENGTH];
    int weight;
    ArcNode *p, *q;
    ArcNode *pTmp;
    for (int i = 0; i < g.arcnum; i++)
    {
        
        memset(arcHead, 0, LENGTH);
        memset(arcTail, 0, LENGTH);
        fcin>>arcTail>>arcHead>>weight;
        int x = LocateVex(g, arcHead);
        int y = LocateVex(g, arcTail);
        p = new ArcNode;
        q = new ArcNode;
        p->adjvex = y;
        p->nextarc = NULL;
        p->weight = weight;
        q->adjvex = x;
        q->nextarc = NULL;
        q->weight = weight;
        if (NULL == g.vertices[x].firstarc)
        { 
            g.vertices[x].firstarc = p;
        }
        else
        {
            for (pTmp = g.vertices[x].firstarc; NULL != pTmp->nextarc; pTmp = pTmp->nextarc)
            {
                ;
            }
            pTmp->nextarc = p;
            
        }
        if (NULL == g.vertices[y].firstarc)
        { 
            g.vertices[y].firstarc = q;
        }
        else
        {
            for (pTmp = g.vertices[y].firstarc; NULL != pTmp->nextarc; pTmp = pTmp->nextarc)
            {
                ;
            }
            pTmp->nextarc = q;
        }
        /*p->adjvex = y;
        p->nextarc = g.vertices[x].firstarc;
        p->weight = weight;
        g.vertices[x].firstarc = p;

        q->adjvex = x;
        q->nextarc = g.vertices[y].firstarc;
        q->weight = weight;
        g.vertices[y].firstarc = q;*/
    }
}

//v的第一个邻接点
int FirstAdjVex(const ALGraph &g, int v)
{
    if ( NULL != g.vertices[v].firstarc)
    {
        return g.vertices[v].firstarc->adjvex;
    }
    return -1;
}

//v相对于w的下一个邻接点
int NextAdjVex(const ALGraph &g, int v, int w)
{
    ArcNode *p;
    for (p = g.vertices[v].firstarc; NULL != p; p = p->nextarc)
    {
        if (p->adjvex == w && p->nextarc != NULL)
        {
            return p->nextarc->adjvex;
        }
    }
    return -1;
}

//*********************************邻接表***********************************end

//*********************************关节点***********************************begin
int countNum = 0;
int visited[MAX_VERTEX_NUM];
int low[MAX_VERTEX_NUM];

void DFSArticul(ALGraph g, int v0)
{
    int minVal;
    visited[v0] = minVal = ++countNum;  //1、将minVal赋值为visited,即为深度遍历的次序号
    for (ArcNode *p = g.vertices[v0].firstarc; NULL != p; p = p->nextarc)
    {
        int w = p->adjvex;
        if (0 == visited[w])
        {
            DFSArticul(g, w);
            if (low[w] < minVal)  //2、如果minVal大于子树的low值,则赋予子树的low给minVal
            {
                minVal = low[w];
            }
            if (low[w] >= visited[v0])
            {
                cout<<"关节点为:"<<g.vertices[v0].data<<endl;
            }
        }
        else if (visited[w] < minVal) //3、w是v0的祖先
        {
            minVal = visited[w];
        }
    }
    low[v0] = minVal;
}

void FindArticul(ALGraph g)
{
    countNum = 1;
    visited[0] = 1;
    for (int i = 1; i < g.vexnum; i++)
    {
        visited[i] = 0;
    }
    ArcNode *p = g.vertices[0].firstarc;
    int v = p->adjvex;
    DFSArticul(g, v);
    if (countNum < g.vexnum)
    {
        cout<<"关节点为:"<<g.vertices[0].data<<endl;
        while (NULL != p->nextarc)
        {
            p = p->nextarc;
            v= p->adjvex;
            if (0 == visited[v])
            {
                DFSArticul(g, v);
            }
        }
    }

}

//*********************************关节点***********************************end
//辅助函数,设置控制台的颜色
void SetConsoleTextColor(WORD dwColor)
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    if (INVALID_HANDLE_VALUE == handle)
    {
        return;
    }
    SetConsoleTextAttribute(handle, dwColor);
}
运行的界面如下:

建造图的articul.txt文件如下:
8
V1 V2 V3 V4 V5 V6 V7 V8
10
V1 V2 6
V1 V3 5
V1 V4 5
V1 V5 5
V2 V3 3
V4 V6 3
V5 V6 5
V6 V7 6
V6 V8 4
V7 V8 4
 
原文地址:https://www.cnblogs.com/venow/p/2647162.html