关节点(邻接表)
#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