java 最短路径 邻接表_(邻接表)最短路径算法

Dijkstra算法:

思想:找到距离原点最近的一个顶点,然后以该点为中心进行扩展,最终得到源点到其余各点的最短路径。

缺点:无法解决带负边的图论问题。

输入样例:

6 9 1 (6个点 9条边 起点为1)

1 2 1

1 3 12

2 3 9

2 4 3

3 5 5

4 3 4

4 5 13

4 6 15

5 6 4

输出样例:

0 1 8 4 13 17 (源点到各点的最短距离)

#include

#include

#include

#include

#include

#include

#include

using namespace std;

const int inf=999999;//0x7fffff

const long long mod=1e9+7;

const double PI=acos(-1);

int n,m;

int ans=9999999;

bool vis[105];

int dis[105];

struct node{

int u;

int w;

node(int uu,int ww){

u=uu;

w=ww;

}

};

vector v[105];

void Dijkstra(int s){                        //Dijkstra算法为单源最短路径算法 s 为起点

memset(dis,inf,sizeof(dis));             //dis数组表示起点 s 到每个点的最小路径

dis[s]=0;

int min,minp;

for(int i=1;i<=n;i++){                 //遍历dis数组的每一个最短路径

min=inf;

for(int j=1;j<=n;j++){

if(!vis[j]&&dis[j]

min=dis[j];

minp=j;

}

}

vis[minp]=1;

for(int u=0;u

node no=v[minp][u];

if(!vis[no.u]&&dis[no.u]>dis[minp]+no.w){

dis[no.u]=dis[minp]+no.w;

}

}

}

}

int main()

{

int x,y,value,s;

cin>>n>>m>>s;

for(int i=1;i<=n;i++){

dis[i]=inf;

}

for(int i=0;i

cin>>x>>y>>value;

v[x].push_back(node(y,value));

}

Dijkstra(s);                        //s 为起点

for(int i=1;i<=n;i++){              //输出s 到各个点的最短路径

cout<

}

return 0;

}

Bellman_Floyd算法:

思路:将起使元素入队,队首元素出队,遍历队首元素连接的节点,每次判断能不能通过队首元素使起使元素到此时遍历的节点,使最短路径变小并更新,到队列为空为止。

有点类似于宽度优先搜索,只是宽度优先搜索出队后不再入队,该算法需要不断更新最短路径,可能需要重新入队。

优点:可以解决带负边的问题。

输入样例:

5 7 1     (5个点 7条边 起点元素1)

1 2 2

1 5 10

2 3 3

2 5 7

3 4 4

4 5 5

5 3 6

输出样例:

0 2 5 9 9(起点到各个点的最短路径)

#include #include#include#include#include#include#include#include

using namespacestd;const int inf=999999;//0x7fffff

const long long mod=1e9+7;const double PI=acos(-1);intn,m;int ans=9999999;bool vis[105];int dis[105],u[105];structnode{intv;intw;

node(int vv,intww){

v=vv;

w=ww;

}

};

vector v[105];

queueq;void Bellman_Floyd(ints){

memset(dis,inf,sizeof(dis)); //初始化设置所有节点都不可达

dis[s]=0;

vis[s]=1;

q.push(s);while(!q.empty()){int no = q.front(); //no队首元素序号 nd队首元素连接节点

q.pop();for(int i=0;i

node nd=v[no][i];if(dis[nd.v]>dis[no]+nd.w){

dis[nd.v]=dis[no]+nd.w;if(!vis[nd.v]){ //此时队首相连节点不在队列中 需要添加队列中并置为访问

vis[nd.v]=1;

q.push(nd.v);

}

}

}

vis[no]=0;

}

}intmain()

{intx,y,value,s;

cin>>n>>m>>s;for(int i=1;i<=m;i++){

cin>>x>>y>>value;

v[x].push_back(node(y,value));

}

Bellman_Floyd(s);for(int i=1;i<=n;i++){

cout<

}return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值