//单源最短路
//有向图 能解决负权 负圈会呈现一定形式,可加入判断,判断是否有负圈
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXN 10000
#define MAXM 1000
#define INF 0X7FFFFFFF
struct node{
int from;
int to;
int weight;
int next;
}edge[MAXM];
int head[MAXN+1],cnt;
int n,m;
void Init(){
cnt=0;
memset(edge,0,sizeof(edge));
memset(head,0,sizeof(head));
}
void Add(int x,int y,int z){
cnt++;
edge[cnt].from=x;
edge[cnt].to=y;
edge[cnt].weight=z;
edge[cnt].next=head[x];
head[x]=cnt;
}
void Bellman_Ford(int start){
int *dis=new int[n+1];
int flag;
for(int i=1;i<=n;i++){
dis[i]=INF;
}
dis[start]=0;
for(int i=1;i<n;i++){//第一轮,最多经过一条边的最短路径,第二轮,最多经过两条边......第n-1轮,最多经过n-1条边。
// 不可能n条边,否则就有回路了,有回路的路径肯定不是最短的,若回路为正,则明显不为最短。若回路为负,则不存在最短
flag=0;//用于判断本轮有没有更新
for(int j=1;j<=cnt;j++){
if(dis[edge[j].from]!=INF&&dis[edge[j].to]>dis[edge[j].from]+edge[j].weight){
dis[edge[j].to]=dis[edge[j].from]+edge[j].weight;
flag=1;
}
}
if(!flag){
break;
}
}
//判断负圈 有负圈的图,最短路径无意义
//若还可以更新,则有负圈
for(int j=1;j<=cnt;j++){
if(dis[edge[j].from]!=INF&&dis[edge[j].to]>dis[edge[j].from]+edge[j].weight){
return;
}
}
for(int i=1;i<=n;i++){
printf("%d%c",dis[i],i==n?'\n':' ');
}
}
int main(){
int start,x,y,z;
cin>>n>>m>>start;
for(int i=1;i<=n;i++){
cin>>x>>y>>z;
Add(x,y,z);
}
Bellman_Ford(start);
return 0;
}
//无向图 有负权结果就很乱 因为在负权那里转圈,想当于负圈
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXN 10000
#define MAXM 1000
#define INF 0X7FFFFFFF
struct node{
int from;
int to;
int weight;
int next;
}edge[MAXM];
int head[MAXN+1],cnt;
int n,m;
void Init(){
cnt=0;
memset(edge,0,sizeof(edge));
memset(head,0,sizeof(head));
}
void Add(int x,int y,int z){
cnt++;
edge[cnt].from=x;
edge[cnt].to=y;
edge[cnt].weight=z;
edge[cnt].next=head[x];
head[x]=cnt;
}
void Bellman_Ford(int start){
int *dis=new int[n+1];
int flag;
for(int i=1;i<=n;i++){
dis[i]=INF;
}
dis[start]=0;
for(int i=1;i<n;i++){
flag=0;//用于判断本轮有没有更新
for(int j=1;j<=cnt;j++){
if(dis[edge[j].from]!=INF&&dis[edge[j].to]>dis[edge[j].from]+edge[j].weight){
dis[edge[j].to]=dis[edge[j].from]+edge[j].weight;
flag=1;
}
}
if(!flag){
break;
}
}
for(int i=1;i<=n;i++){
printf("%d%c",dis[i],i==n?'\n':' ');
}
}
int main(){
int start,x,y,z;
cin>>n>>m>>start;
for(int i=1;i<=n;i++){
cin>>x>>y>>z;
Add(x,y,z);
Add(y,x,z);
}
Bellman_Ford(start);
return 0;
}
Bellman-Ford算法
最新推荐文章于 2024-09-27 16:53:40 发布