1适用于有向无环图求最短路径
2将算法稍微改进,即可求关键路径
3运行时间与邻接表的大小呈线性关系
算法思想:
1:对图进行拓扑排序;
2 :init_signal_source(g, s);
3:按拓扑序列取出的顶点v,对与v相邻的顶点u进行relax(v,u,w);
# include<iostream>
# include<cstring>
# include<stack>
# define inf 0x3f3f3f3f
# define nil -1
using namespace std;
const int maxn=100+5;
typedef struct arcnode{
int adjnode;
int weight;
arcnode *nextarc;
}arcnode;
typedef struct vnode{
int data;
arcnode *firstarc;
}vnode;
typedef struct graph{
vnode vertexs[maxn];
int vertexnum; //顶点数目
int edgenum; //边数目
}graph;
int pre[maxn];
int dis[maxn];
int vis[maxn];
stack<int> ss; //存放拓扑序列
int find(graph g,int v)
{
for(int i=0;i<g.vertexnum;i++)
{
if(g.vertexs[i].data==v)
return i;
}
}
void init(graph &g)
{
cin>>g.vertexnum>>g.edgenum;
for(int i=0;i<g.vertexnum;i++)
{
cin>>g.vertexs[i].data;
g.vertexs[i].firstarc=NULL;
}
int u,v,w;
for(int i=0;i<g.edgenum;i++)
{
cin>>u>>v>>w;
arcnode *s=new arcnode();
int index_u=find(g,u);
int index_v=find(g,v);
s->adjnode=index_v;
s->weight=w;
s->nextarc=g.vertexs[index_u].firstarc;
g.vertexs[index_u].firstarc=s;
}
}
void relax(int u,int v,int w)
{
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
pre[v]=u;
}
}
void init_signal_source(graph g,int s)
{
for(int i=0;i<g.vertexnum;i++)
{
pre[i]=nil;
dis[i]=inf;
}
dis[s]=0; //源点距离初始化为0
}
void printpath(graph g,int s,int v)
{
if(v==s)
{
cout<<g.vertexs[s].data;
}
else if(pre[v]==nil)
{
cout<<"no path from "<<g.vertexs[s].data <<"to "<<g.vertexs[v].data;
}
else {
printpath(g,s,pre[v]);
cout<<"->"<<g.vertexs[v].data;
}
}
bool topologicalsort(graph g,int v)
{
vis[v]=-1; //标记正在访问
arcnode *s=g.vertexs[v].firstarc;
while(s)
{
if(vis[s->adjnode]<0)
return false;
if(!vis[s->adjnode]&&!topologicalsort(g,s->adjnode))
return false;
s=s->nextarc;
}
vis[v]=1; //访问结束
ss.push(v);
return true;
}
void dag_shortest_path(graph g,int s)
{
for(int i=0;i<g.vertexnum;i++)
if(!vis[i])
topologicalsort(g,i);
init_signal_source(g,s);
while(!ss.empty())
{
int k=ss.top();
ss.pop();
arcnode *w=g.vertexs[k].firstarc;
while(w)
{
relax(k,w->adjnode,w->weight);
w=w->nextarc;
}
}
}
int main()
{
graph g;
init(g);
int v;
cin>>v;
int index_v=find(g,v);
memset(vis,0,sizeof(vis));
dag_shortest_path(g,index_v);
for(int i=0;i<g.vertexnum;i++)
{
if(i!=index_v)
{
printpath(g,index_v,i);
if(dis[i]!=inf)
cout<<" "<<dis[i]<<endl;
else cout<<"正无穷"<<endl;
}
}
return 0;
}