/*
Bellmam_Ford 伪代码:
Bellman-Ford(G,w,s) :boolean //图G ,边集 函数 w ,s为源点
for each vertex v ∈ V(G) do //初始化 1阶段
d[v] ←+∞
d[s] ←0; //1阶段结束
for i=1 to |v|-1 do //2阶段开始,双重循环。
for each edge(u,v) ∈E(G) do //边集数组要用到,穷举每条边。
If d[v]> d[u]+ w(u,v) then //松弛判断
d[v]=d[u]+w(u,v) //松弛操作 2阶段结束
for each edge(u,v) ∈E(G) do
If d[v]> d[u]+ w(u,v) then
Exit false
Exit true
*/
#include<stdio.h>
#define N 505
#define M 5210
#define INF 100000000
struct Edge
{
int s,e,w;
}edge[M];
int d[N];
int n,m,w,eNum;
void AddEdge(int s,int e,int w)
{
edge[eNum].s=s;
edge[eNum].e=e;
edge[eNum].w=w;
eNum++;
}
void Bellman_Ford()
{
for(int i=1;i<=n;i++)
d[i]=INF;
d[1]=0;
int flag;
for(int i=0;i<n-1;i++)//求最短路
{
flag=1;
for(int j=0;j<eNum;j++)
{
int u=edge[j].s;
int v=edge[j].e;
if(d[v]>d[u]+edge[j].w)
{
d[v]=d[u]+edge[j].w;
flag=0;//优化
}
}
if(flag)
{
printf("NO\n");
return;
}
}
for(int j=0;j<eNum;j++)//判负环
{
int u=edge[j].s;
int v=edge[j].e;
if(d[v]>d[u]+edge[j].w)
{
printf("YES\n");//还能松弛,有负环
return;
}
}
printf("NO\n");
return;
}
//Floyd
/*
//伪代码
// dist(i,j) 为从节点i到节点j的最短距离,不直接相连记为 INF
For i←1 to n do
For j←1 to n do
d(i,j) = w(i,j)
For k←1 to n do // k为“媒介节点”
For i←1 to n do
For j←1 to n do
if (d(i,k) + d(k,j) < d(i,j)) then // 是否是更短的路径?
d(i,j) = d(i,k) + d(k,j)
*/
void Floyd()
{
for(int k=1;k<=q;k++)
for(int i=1;i<=q;i++)
for(int j=1;j<=q;j++)
{
if(d[i][j]>d[i][k]+d[k][j])
d[i][j]=d[i][k]+d[k][j];
}
}