#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