/*
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];
}
}