Bellman_ford或spfa 判斷圖是否存在負環
阿新 • • 發佈:2019-02-19
/* 判斷負環的兩種方法: Spfa思想:如果存在一個點進入佇列的次數超過N次,則存在負環。 bellman_ford思想:對所有的邊進行v-1 鬆弛即如果 dis[u]+map[u][v] < dis[v] 則 dis[v] = dis[u]+map[u][v] 若v-1次鬆弛之後還能進行鬆弛,說明原圖存在負環。複雜度 0(VE) */ //bellman_ford判斷 #include <iostream> using namespace std; const int MAXN = 1000; int map[MAXN][MAXN]; int dis[MAXN]; int front[MAXN]; struct Edge { int s; int e; }e[MAXN*MAXN]; //如果返回-1,則表示有負環。 否則返回dis[end] //起點,終點,n個點,m條邊. 頂點編號1,2...n int bellman_ford(int start, int end, int n, int m) { memset(dis,0x7f,sizeof(dis)); //初始化無窮大 dis[start] = 0; for(int i=0; i<n-1; i++) //n-1次鬆弛 { for(int j=0; j<m; j++) { if(dis[e[j].s] + map[e[j].s][e[j].e] < dis[e[j].e]) { dis[e[j].e] = dis[e[j].s] + map[e[j].s][e[j].e]; } } } //判斷是否能繼續鬆弛 int flag = 0; for(int i=0; i<m; i++) { if(dis[e[i].s] + map[e[i].s][e[i].e] < dis[e[i].e]) { flag = 1; dis[e[i].e] = dis[e[i].s] + map[e[i].s][e[i].e]; break; } } if(flag) { return -1; } return dis[end]; } int main() { int n,m; int a,b,c; while(cin>>n>>m) { for(int i=0; i<m; i++) { cin>>a>>b>>c; map[a][b] = c; //把邊儲存起來 e[i].s = a; e[i].e = b; } int ans = bellman_ford(1,n,n,m); if(ans == -1) { cout<<"ERROR"<<endl; } else { cout<<ans<<endl; } } return 0; }