#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100
#define MAXSIZE 20
#define OK 1
#define ERROR 0
typedef char VertexType;
typedef int EdgeType;
#define INFINITY 65535 /*用65535来代表∞*/
#define UNVISITED -1
#define VISITED 1
typedef struct
{
int index;
int length;
int pre;
}Dist;
typedef struct
{
int from;
int to;
EdgeType weight;
}Edge;
typedef struct
{
int numVertex;
int numEdge;
VertexType vexs[MAXVEX];
int Indegree[MAXVEX];
int Mark[MAXVEX];
EdgeType arc[MAXVEX][MAXVEX];
Dist D[MAXVEX];
}Graph;
typedef int Status;
typedef Edge ElemType;
typedef struct
{
ElemType heapArray[MAXSIZE];
int length;
}MinHeap;
Edge FirstEdge(Graph * G,int oneVertex);
Edge NextEdge(Graph * G,Edge preEdge);
bool IsEdge(Edge oneEdge);
Status Init_heapArray(Graph * G,MinHeap * M,int s)
{
for(Edge e=FirstEdge(G,s);IsEdge(e);e=NextEdge(G,e))
{
M->heapArray[M->length]=e;
M->length++;
}
return OK;
}
Status Init_MinHeap(Graph * G,MinHeap * M,int s)
{
M->length=0;
Init_heapArray(G,M,s);
return OK;
}
int MinHeap_Leftchild(int pos)
{
return 2*pos+1;
}
int MinHeap_Rightchild(int pos)
{
return 2*pos+2;
}
int MinHeap_Parent(int pos)
{
return (pos-1)/2;
}
void MinHeap_SiftDown(MinHeap * M,int left)
{
int i=left;
int j=MinHeap_Leftchild(i);
ElemType temp=M->heapArray[i];
while(j<M->length)
{
if((j<M->length-1)&&(M->heapArray[j].weight>M->heapArray[j+1].weight))
{
j++;
}
if(temp.weight>M->heapArray[j].weight)
{
M->heapArray[i]=M->heapArray[j];
i=j;
j=MinHeap_Leftchild(j);
}
else
{
break;
}
}
M->heapArray[i]=temp;
}
void MinHeap_SiftUp(MinHeap * M,int position)
{
int temppos=position;
ElemType temp=M->heapArray[temppos];
while((temppos>0) && (M->heapArray[MinHeap_Parent(temppos)].weight>temp.weight))
{
M->heapArray[temppos]=M->heapArray[MinHeap_Parent(temppos)];
temppos=MinHeap_Parent(temppos);
}
M->heapArray[temppos]=temp;
}
void Swap(MinHeap * M,int data1,int data2)
{
ElemType temp;
temp=M->heapArray[data1];
M->heapArray[data1]=M->heapArray[data2];
M->heapArray[data2]=temp;
}
void Create_MinHeap(MinHeap * M)
{
for(int i=M->length/2-1;i>=0;i--)
{
MinHeap_SiftDown(M,i);
}
}
Status MinHeap_Insert(MinHeap * M,ElemType NewElem)
{
if(M->length==MAXSIZE)
{
return ERROR;
}
M->heapArray[M->length]=NewElem;
MinHeap_SiftUp(M,M->length);
M->length++;
return OK;
}
Status MinHeap_Delete(MinHeap * M,ElemType * MinElem)
{
if(M->length==0)
{
printf("不能删除,堆已空!\n");
return ERROR;
}
else
{
Swap(M,0,--M->length);
if(M->length>1)
{
MinHeap_SiftDown(M,0);
}
*MinElem=M->heapArray[M->length];
return OK;
}
}
void InitGraph(Graph * G,int numVert,int numEd )
{
G->numVertex=numVert;
G->numEdge=numEd;
for(int i=0;i<numVert;i++)
{
G->Mark[i]=UNVISITED;
G->Indegree[i]=0;
for(int j=0;j<numVert;j++)
{
G->arc[i][j]=INFINITY;
if(i==j)
{
G->arc[i][j]=0;
}
}
}
return ;
}
void InitDist(Graph * G,int s)
{
for(int i=0;i<G->numVertex;i++)
{
G->D[i].index=i;
G->D[i].length=INFINITY;
G->D[i].pre=s;
}
G->D[s].length=0;
}
bool IsEdge(Edge oneEdge)
{
if(oneEdge.weight>0 && oneEdge.weight!=INFINITY && oneEdge.to>=0)
{
return true;
}
else
{
return false;
}
}
void CreatGraph(Graph * G)
{
int i,j,k,w;
printf("请输入%d个顶点元素:\n",G->numVertex);
for(i=0;i<G->numVertex;i++)
{
scanf(" %c",&G->vexs[i]);
}
for(k=0;k<G->numEdge;k++)
{
printf("请输入边(Vi,Vj)的下标Vi,Vj,和权重w:\n");
scanf("%d%d%d",&i,&j,&w);
G->Indegree[j]++;
G->arc[i][j]=w;
}
}
int VerticesNum(Graph * G)
{
return G->numVertex;
}
Edge FirstEdge(Graph * G,int oneVertex)
{
Edge firstEdge;
firstEdge.from=oneVertex;
for(int i=0;i<G->numVertex;i++)
{
if(G->arc[oneVertex][i]!=0 && G->arc[oneVertex][i]!=INFINITY)
{
firstEdge.to=i;
firstEdge.weight=G->arc[oneVertex][i];
break;
}
}
return firstEdge;
}
int ToVertex(Edge oneEdge)
{
return oneEdge.to;
}
Edge NextEdge(Graph * G,Edge preEdge)
{
Edge myEdge;
myEdge.from=preEdge.from;
if(preEdge.to<G->numVertex)
for(int i=preEdge.to+1;i<G->numVertex;i++)
{
if(G->arc[preEdge.from][i]!=0 && G->arc[preEdge.from][i]!=INFINITY)
{
myEdge.to=i;
myEdge.weight=G->arc[preEdge.from][i];
break;
}
}
return myEdge;
}
void Insert(Graph * G,MinHeap * M,int oneVertex)
{
for(Edge e=FirstEdge(G,oneVertex);IsEdge(e);e=NextEdge(G,e))
{
MinHeap_Insert(M,e);
}
}
void print_Dist(Graph * G);
void Dijkstra(Graph * G,MinHeap * M,int s)
{
InitDist(G,s);
Init_MinHeap(G,M,s);
for(int i=0;i<G->numVertex;i++)
{
bool FOUND=false;
Edge d;
MinHeap_Delete(M,&d);
int v=d.from;
int nv=d.to;
G->Mark[nv]=VISITED;
int count=0;
for(Edge e=FirstEdge(G,v);IsEdge(e);e=NextEdge(G,e))
{
count++;
if(G->D[ToVertex(e)].length>(G->D[v].length+e.weight))
{
G->D[ToVertex(e)].length=G->D[v].length+e.weight;
G->D[ToVertex(e)].pre=v;
}
}
Insert(G,M,nv);
}
}
void print_Dist(Graph * G)
{
for(int i=0;i<G->numVertex;i++)
{
printf("元素:%c index:%d length:%d pre:%d\n",G->vexs[i],G->D[i].index,G->D[i].length,G->D[i].pre);
}
printf("\n");
}
int main()
{
Graph G;
MinHeap M;
int numVert,numEd;
printf("请输入顶点数和边数:\n");
scanf("%d%d",&numVert,&numEd);
InitGraph(&G,numVert,numEd );
CreatGraph(&G);
Dijkstra(&G,&M,0);
print_Dist(&G);
return 0;
}