//spfa算法模板(鄰接矩陣):
//c++ code:
void spfa(int s){
for(int i=0; i<=n; i++) dis[i]=99999999; //初始化每點i到s的距離
dis[s]=0; vis[s]=1; q[1]=s; 隊列初始化,s爲起點
int i, v, head=0, tail=1;
while (head<tail){ 隊列非空
head++;
v=q[head]; 取隊首元素
vis[v]=0; 釋放隊首結點,因爲這節點可能下次用來鬆弛其它節點,重新入隊
for(i=0; i<=n; i++) 對所有頂點
if (a[v][i]>0 && dis[i]>dis[v]+a[v][i]){
dis[i] = dis[v]+a[v][i]; 修改最短路
if (vis[i]==0){ 如果擴展結點i不在隊列中,入隊
tail++;
q[tail]=i;
vis[i]=1;
}
}
}
}
轉自https://blog.csdn.net/xunalove/article/details/70045815
以上是BFS的spfa算法,可能會超時
DFS spfa
#include <iostream>
using namespace std;
int q[10001], dis[201], a[201][201], b[201][201];
bool vis[201];
int n, m, s, t;
bool flag=false;
void spfa(int s){
if(flag) return;
if(vis[s])//如果有一條邊經歷過兩次就是存在負環
{
flag=true;
return;
}
else vis[s]=1;
for(int i=1; i<=b[s][0]; i++)
if (dis[b[s][i]] > dis[s]+a[s][b[s][i]]){
dis[b[s][i]] = dis[s]+a[s][b[s][i]];
spfa(b[s][i]);
if(flag) return;
}
}
int main(){
int x, y, z,w;
int t;
cin>>t;
while(t--){
flag=false;
cin >> n >> m>> w;
for(int i=0; i<m; i++){
cin >> x >> y >> z;
//if (a[x][y]!=0 && z>a[x][y]) continue;
b[x][0]++; b[x][b[x][0]]=y; a[x][y]=z;
b[y][0]++; b[y][b[y][0]]=x; a[y][x]=z;
}
for(int i=0;i<w;i++)
{
cin >> x >> y >> z;
//if (a[x][y]!=0 && z>a[x][y]) continue;
b[x][0]++; b[x][b[x][0]]=y; a[x][y]=-z;//b[x][0]表示從頂點x出發有多少條邊 b[x][b[x][0]]=y 存儲的是從x出發的第b[x][0]條邊的終點
b[y][0]++; b[y][b[y][0]]=x; a[y][x]=-z;
}
for(int i=0; i<=n; i++) dis[i]=99999999;
dis[1]=0;
spfa(s);
if (flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}