# include<iostream>
# 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 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
}
bool bellman(graph g,int s)
{
init_signal_source(g,s); //初始化
for(int w=1;w<g.vertexnum;w++)//如果不存在环,那么最短路径最多包含顶点数-1个顶点(源点除去),
//故可以进行顶点数-1遍松弛操作找到最短路径
{
for(int i=0;i<g.vertexnum;i++)
{
arcnode* k=g.vertexs[i].firstarc;
while(k)
{
int j=k->adjnode;
relax(i,j,k->weight);
k=k->nextarc;
}
}
}
for(int i=0;i<g.vertexnum;i++) //对每一条边进行检查
{
arcnode* k=g.vertexs[i].firstarc;
while(k)
{
int j=k->adjnode;
if(dis[j]>dis[i]+k->weight) //进行松弛操作过后的dis[j]只能<=dis[i]+k->weight 否侧出现负权回路
return false;
k=k->nextarc;
}
}
return true;
}
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;
}
}
int main()
{
graph g;
init(g);
int v;
cin>>v;
int index_v=find(g,v);
if(!bellman(g,index_v))
{
cout<<"存在负权回路"<<endl;
return 0;
}
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;
}
单源最短路径(bellman算法)
最新推荐文章于 2024-06-25 21:37:38 发布