图结构的邻接表表示
#include<iostream>
#include<queue>
using namespace std;
#define MaxVertexNum 100
typedef int Vertex;
typedef int WeightType;
typedef char DataType;
bool Visited[MaxVertexNum]= {false};
typedef struct ENode* PtrToENode;
struct ENode {
Vertex V1,V2;
WeightType Weight ;
};
typedef PtrToENode Edge;
typedef struct AdjVNode* PtrToAdjVNode;
struct AdjVNode {
Vertex Adjx;
WeightType Weight;
PtrToAdjVNode Next;
};
typedef struct Vnode {
PtrToAdjVNode FirstEdge;
DataType Data;
} AdjList[MaxVertexNum];
typedef struct GNode* PtrToGNode;
struct GNode {
int Nv;
int Ne;
AdjList G;
};
typedef PtrToGNode LGraph;
LGraph CreateGraph(int VertexNum) {
Vertex V;
LGraph Graph;
Graph=(LGraph)malloc(sizeof(struct GNode));
Graph->Ne=0;
Graph->Nv=VertexNum;
for(V=0; V<Graph->Nv; V++)
Graph->G[V].FirstEdge=NULL;
return Graph;
}
void InsertEdge(LGraph Graph,Edge E) {
PtrToAdjVNode NewNode;
NewNode =(PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode->Adjx=E->V2;
NewNode->Weight=E->Weight;
NewNode->Next=Graph->G[E->V1].FirstEdge;
Graph->G[E->V1].FirstEdge=NewNode;
NewNode=(PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode->Adjx=E->V1;
NewNode->Weight=E->Weight;
NewNode->Next=Graph->G[E->V2].FirstEdge;
Graph->G[E->V2].FirstEdge=NewNode;
}
LGraph BuildGraph() {
LGraph Graph;
Edge E;
Vertex V;
int Nv,i;
scanf("%d",&Nv);
Graph=CreateGraph(Nv);
scanf("%d",&(Graph->Ne));
if(Graph->Ne!=0) {
E=(Edge)malloc(sizeof(struct ENode));
for(i=0; i<Graph->Ne; i++) {
scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
InsertEdge(Graph,E);
}
}
for(V=0; V<Graph->Nv; V++)
scanf("%c",&(Graph->G[V].Data));
return Graph;
}
void Visit(Vertex V) {
printf("正在访问顶点%d\n",V);
}
void DFS(LGraph Graph,Vertex V,void(*Visit)(Vertex)) {
PtrToAdjVNode W;
Visit(V);
Visited[V]=true;
for(W=Graph->G[V].FirstEdge; W; W=W->Next)
if(!Visited[W->Adjx])
DFS(Graph,W->Adjx,Visit);
}
void Unweighted(LGraph Graph,int dist[],int path[],Vertex S) {
queue<int >Q;
Vertex V;
PtrToAdjVNode W;
dist[S]=0;
Q.push(S);
while(!Q.empty()) {
V=Q.front();
Q.pop();
for(W=Graph->G[V].FirstEdge; W; W=W->Next) {
if(dist[W->Adjx]==-1) {
dist[W->Adjx]=dist[V]+1;
path[W->Adjx]=V;
Q.push(W->Adjx);
}
}
}
}
typedef Vertex ELementType;
typedef Vertex SetName;
typedef ElementType SetType[MaxVertexNum];
void InitializeVSet(SetType S,int N) {
ELementType X;
for(X=0; X<N; X++)S[X]=-1;
}
void Union(SetType S,SetName Root1,SetName Root2) {
if(S[Root2]<S[Root1]) {
S[Root2]+=S[Root1];
S[Root1]=Root2;
} else {
S[Root1]+=S[Root2];
S[Root2]=Root1;
}
}
SetName Find(SetType S,ElementType X) {
if(S[X]<0)
return X;
else
return S[X]=Find(S,S[X]);
}
bool CheckCycle(SetType Vset,Vertex V1,Vertex V2) {
Vertex Root1,Root2;
Root1=Find(Vset,V1);
Root2=Find(Vset,V2);
if(Root1==Root2)
return false ;
else {
Union(Vset,Root1,Root2);
return true;
}
}
void PercDown(Edge Eset,int p,int N) {
int Parent,Child;
struct ENode X;
X=Eset[p];
for(Parent=p; (Parent*2+1)<N; Parent=Child) {
Child=Parent*2+1;
if(Child!=N-1)&&(Eset[Child].Weight>Eset[Child+1].Weight)
Child++;
if(X.Weight<=Eset[Child].Weight)break;
else Eset[Parent]=Eset[Child];
}
Eset[Parent]=X;
}
void InitializeESet(LGraph Graph, Edge Eset) {
Vertex V;
PtrToAdjVNode W;
int ECount;
ECount=0;
for(V=0; V<Graph->Nv; V++) {
for(W=Graph->G[V].FirstEdge; W; W=W->Next)
if(V<W.Adjx) {
Eset[ECount].V1=V;
Eset[ECount].V2=W->Adjx;
Eset[ECount++].Weight=W->Weight;
}
}
for(ECount=Graph->Ne/2; ECount>=0; ECount--)
PercDown(Eset,ECount,Graph->Ne);
}
int GetEdge(Edge Eset,int CurrentSize) {
Swap(&Eset[0],&Eset[CurrentSize-1]);
PercDown(Eset,0,CurrentSize-1);
return CurrentSize-1;
}
int Kruskal(LGraph Graph,LGraph MST) {
WeightType TotalWeight;
int ECount,NextEdge;
SetType VSet;
Edge Eset;
InitializeVSet( VSet, Graph->Nv );
ESet = (Edge)malloc( sizeof(struct ENode)*Graph->Ne );
InitializeESet( Graph, Eset );
MST = CreateGraph(Graph->Nv);
TotalWeight = 0;
ECount = 0;
NextEdge = Graph->Ne;
while ( ECount < Graph->Nv-1 ) {
NextEdge = GetEdge( ESet, NextEdge );
if (NextEdge < 0)
break;
if ( CheckCycle( VSet, ESet[NextEdge].V1, ESet[NextEdge].V2 )==true ) {
InsertEdge( MST, ESet+NextEdge );
TotalWeight += ESet[NextEdge].Weight;
ECount++;
}
}
if ( ECount < Graph->Nv-1 )
TotalWeight = -1;
return TotalWeight;
}
bool TopSort( LGraph Graph, Vertex TopOrder[] )
{
int Indegree[MaxVertexNum], cnt;
Vertex V;
PtrToAdjVNode W;
Queue Q = CreateQueue( Graph->Nv );
for (V=0; V<Graph->Nv; V++)
Indegree[V] = 0;
for (V=0; V<Graph->Nv; V++)
for (W=Graph->G[V].FirstEdge; W; W=W->Next)
Indegree[W->AdjV]++;
for (V=0; V<Graph->Nv; V++)
if ( Indegree[V]==0 )
AddQ(Q, V);
cnt = 0;
while( !IsEmpty(Q) ){
V = DeleteQ(Q);
TopOrder[cnt++] = V;
for ( W=Graph->G[V].FirstEdge; W; W=W->Next )
if ( --Indegree[W->AdjV] == 0 )
AddQ(Q, W->AdjV);
}
if ( cnt != Graph->Nv )
return false;
else
return true;
}