初学数据结构(带权有向图最短路径&&AOE网关键活动)
初学数据结构(带权有向图最短路径&&AOE网关键活动)
《数据结构教程》第6版上机实验题,P308-309
Dijkstrau算法(expp8-7)
//
// Created by Snow on 2023/4/23.
//
#include"graph.cpp"
void DispPath(MatGraph g,int dist[],int path[],int S[],int v)
{
int i,j,k;
int apath[MAXV],d;
for(i=0;i<g.n;i++)
{
if(S[i]==1&&i!=v)
{
printf("%d->%d:%3d\t路径为:",v,i,dist[i]);
d=0;
apath[d]=i;
k=path[i];
if(k==-1)
printf("路径不存在\n");
else
{
while(k!=v)
{
d++;
apath[d]=k;
k=path[k];
}
d++;
apath[d]=v;
printf("%d",apath[d]);
for(j=d-1;j>=0;j--)
printf(",%d",apath[j]);
printf("\n");
}
}
}
}
void Dijkstra(MatGraph g,int v)
{
int dist[MAXV],path[MAXV];
int S[MAXV];
int mindist,i,j,u;
for(i=0;i<g.n;i++)
{
dist[i]=g.edges[v][i];
S[i]=0;
if(g.edges[v][i]<INF)
path[i]=v;
else
path[i]=-1;
}
S[v]=1;
path[v]=0;
for(i=0;i<g.n-1;i++)
{
mindist=INF;
for(j=0;j<g.n;j++)
if(S[j]==0&&dist[j]<mindist)
{
u=j;
mindist=dist[j];
}
S[u]=1;
for(j=0;j<g.n;j++)
if(S[j]==0)
if(g.edges[u][j]<INF&&dist[u]+g.edges[u][j]<dist[j])
{
dist[j]=dist[u]+g.edges[u][j];
path[j]=u;
}
}
DispPath(g,dist,path,S,v);
}
int main()
{
MatGraph g;
int A[MAXV][MAXV]={{0,5,INF,7,INF,INF},{INF,0,4,INF,INF,INF},{8,INF,0,INF,INF,9},{INF,INF,5,0,INF,6},{INF,INF,INF,5,0,INF},{3,INF,INF,INF,1,0}};
int n=6,e=10;
CreateMat(g,A,n,e);
printf("输出邻接矩阵G:\n");
DispMat(g);
int v=0;
printf("从顶点%d到其他顶点的最短路径为:\n",v);
Dijkstra(g,v);
}
Floyd算法(exp8-8)
//
// Created by Snow on 2023/4/24.
//
#include"graph.cpp"
void DispPath(MatGraph g,int A[][MAXV],int path[][MAXV])
{
int i,j,k,s;
int apath[MAXV],d;
for(i=0;i<g.n;i++)
for(j=0;j<g.n;j++)
{
if(A[i][j]!=INF&&i!=j)
{
printf("从%d到%d的路径为:",i,j);
k=path[i][j];
d=0;
apath[d]=j;
while(k!=i)
{
d++;
apath[d]=k;
k=path[i][k];
}
d++;
apath[d]=i;
printf("%d",apath[d]);
for(s=d-1;s>=0;s--)
printf(",%d",apath[s]);
printf("\t路径长度为:%d\n",A[i][j]);
}
}
}
void Floyd(MatGraph g)
{
int A[MAXV][MAXV],path[MAXV][MAXV];
int i,j,k;
for(i=0;i<g.n;i++)
for(j=0;j<g.n;j++)
{
A[i][j]=g.edges[i][j];
if(i!=j&&g.edges[i][j]<INF)
path[i][j]=i;
else
path[i][j]=-1;
}
for(k=0;k<g.n;k++)
{
for(i=0;i<g.n;i++)
for(j=0;j<g.n;j++)
if(A[i][j]>A[i][k]+A[k][j])
{
A[i][j]=A[i][k]+A[k][j];
path[i][j]=path[k][j];
}
}
DispPath(g,A,path);
}
int main()
{
MatGraph g;
int A[MAXV][MAXV]={{0,5,INF,7,INF,INF},{INF,0,4,INF,INF,INF},{8,INF,0,INF,INF,9},{INF,INF,5,0,INF,6},{INF,INF,INF,5,0,INF},{3,INF,INF,INF,1,0}};
int n=6,e=10;
CreateMat(g,A,n,e);
printf("输出邻接矩阵G:\n");
DispMat(g);
printf("各顶点对的最短路径:\n");
Floyd(g);
}
AOE网(exp8-9)
//
// Created by Snow on 2023/4/24.
//
#include"graph.cpp"
typedef struct
{
int ino;
int eno;
}KeyNode;
bool TopSort(AdjGraph *G,int topseq[])
{
int i,j,n=0;
int st[MAXV];
int top=-1;
ArcNode *p;
for(i=0;i<G->n;i++)
G->adjlist[i].count=0;
for(i=0;i<G->n;i++)
{
p=G->adjlist[i].firstarc;
while(p!=nullptr)
{
G->adjlist[p->adjvex].count++;
p=p->nextarc;
}
}
for(i=0;i<G->n;i++)
if(G->adjlist[i].count==0)
{
top++;
st[top]=i;
}
while(top>-1)
{
i=st[top];
top--;
topseq[n]=i;
n++;
p=G->adjlist[i].firstarc;
while(p!=nullptr)
{
j=p->adjvex;
G->adjlist[j].count--;
if(G->adjlist[j].count==0)
{
top++;
st[top]=j;
}
p=p->nextarc;
}
}
if(n<G->n)
return false;
else
{
for(i=0;i<G->n;i++)
printf("%c ",char(topseq[i]+'A'));
printf("\n");
return true;
}
}
bool KeyPath(AdjGraph *G,int &inode,int &enode,KeyNode keynode[],int &d)
{
int topseq[MAXV];
int i,w;
ArcNode *p;
if(!TopSort(G,topseq))
return false;
inode=topseq[0];
enode=topseq[G->n-1];
int ve[MAXV];
int vl[MAXV];
for(i=0;i<G->n;i++)
ve[i]=0;
for(i=0;i<G->n;i++)
{
p=G->adjlist[i].firstarc;
while(p!=nullptr)
{
w=p->adjvex;
if(ve[i]+p->weight>ve[w])
ve[w]=ve[i]+p->weight;
p=p->nextarc;
}
}
for(i=0;i<G->n;i++)
vl[i]=ve[enode];
for(i=G->n-2;i>=0;i--)
{
p=G->adjlist[i].firstarc;
while(p!=nullptr)
{
w=p->adjvex;
if(vl[w]-p->weight<vl[i])
vl[i]=vl[w]-p->weight;
p=p->nextarc;
}
}
d=-1;
for(i=0;i<G->n;i++)
{
p=G->adjlist[i].firstarc;
while(p!=nullptr)
{
w=p->adjvex;
if(ve[i]==vl[w]-p->weight)
{
d++;
keynode[d].ino=i;
keynode[d].eno=w;
}
p=p->nextarc;
}
}
return true;
}
void DispKeyPath(AdjGraph*G)
{
int inode,enode,d,i;
KeyNode keynode[MAXV];
if(KeyPath(G,inode,enode,keynode,d))
{
printf("从源点%c到汇点%c的关键活动:\n",char(inode='A'),char(enode+'A'));
for(i=0;i<=d;i++)
printf("(%c,%c) ",char(keynode[i].ino+'A'),char(keynode[i].eno+'A'));
printf("\n");
}
else
printf("不能求关键活动\n");
}
int main()
{
AdjGraph *G;
int n=9,e=11;
int A[MAXV][MAXV]={
{ 0, 6, 4, 5 ,INF,INF,INF,INF,INF},
{INF, 0, INF,INF, 1 ,INF,INF,INF,INF},
{INF,INF, 0 ,INF, 1 ,INF,INF,INF,INF},
{INF,INF,INF, 0 ,INF,INF,INF, 2 ,INF},
{INF,INF,INF,INF, 0 , 9 , 7 ,INF,INF},
{INF,INF,INF,INF,INF, 0 ,INF,INF, 2 },
{INF,INF,INF,INF,INF,INF, 0 ,INF, 4 },
{INF,INF,INF,INF,INF,INF,INF, 0 , 4 },
{INF,INF,INF,INF,INF,INF,INF,INF, 0 }};
CreateAdj(G,A,n,e);
printf("输出邻接表G:\n");
DispAdj(G);
DispKeyPath(G);
DestroyAdj(G);
return 0;
}