一道判斷負環的模板題。
這裡主要介紹三種判斷負環的方法。
1.bfs_spfa方法a
我們可以通過記錄每個點的入隊次數來判斷負環是否存在,不難看出:乙個點的入隊次數一旦超過n次,則圖中一定有負環存在。效率不高,不再提供**。
2.bfs_spfa方法b
我們可以記錄每個點到源點最短路上經過了幾個點,一旦超過n個,則負環一定存在,正確性比較顯然、不再贅述。
這個方法為什麼會比方法a效率高呢?舉個例子:在乙個由n個點構成的負環中,方法a要將此環遍歷n次,而方法b遍歷1次就行了.
3.dfs_spfa方法
我們只需將spfa改用dfs實現, 然後應用方法b, 我們就能高效的求出負環了.
愉快的寫完**,提交完成,tle. mengbi了一會下了組資料後發現,其實大多情況下該演算法表現的十分優秀.
dfs_spfa
經過思考發現:如果乙個圖沒有負環的話,以上方法就像乙個弱化版本的spfa,效率大大降低.所以該方法還是要慎用.
總結:
dfs_spfa由於它的不穩定性,還是要慎用的.因為我們無法保證圖中一定有負環(保證了還判什麼).
bfs_spfa的方法a就不考慮了, 方法b比他優秀的多....
總體來說個人認為求穩的話,還是使用bfs_spfa比較保險.
ac**:
這裡給出了bfs方法b和dfs的方法:
#include #include#include
#include
inline
void read(int &x)
int n, m, cnt, x, y, z, t, u, f[2020], d[2020], v[2020], k[2020
], flag;
struct edge e[7000
];inline
void addedge(int a, int b, int z)
inline
bool bfs_spfa(void
) }
return
true;}
void dfs_spfa(int
u) dfs_spfa(e[i].v);
}v[u] = false;}
inline
void work(void
)signed main()
if (!bfs_spfa()) puts("
ye5"
);
else puts("n0"
);
//work();
}
return0;
}
洛谷 3385 負環
暴力列舉 spfa bellman ford 奇怪的貪心 超神搜尋 尋找乙個從頂點1所能到達的負環,負環定義為 乙個邊權之和為負的環。第一行乙個正整數t表示資料組數,對於每組資料 第一行兩個正整數n m,表示圖有n個頂點,m條邊 接下來m行,每行三個整數a b w,表示a b有一條權值為w的邊 若w...
洛谷 P3385 模板 負環
暴力列舉 spfa bellman ford 奇怪的貪心 超神搜尋 輸入格式 第一行乙個正整數t表示資料組數,對於每組資料 第一行兩個正整數n m,表示圖有n個頂點,m條邊 接下來m行,每行三個整數a b w,表示a b有一條權值為w的邊 若w 0則為單向,否則雙向 輸出格式 共t行。對於每組資料,...
洛谷 P3385 模板 負環
題目鏈結 一開始沒注意到他的邊是非負就是雙向的。所以一直wa 用spfa。bfs判斷是否有乙個點進入次數超過n即可。include include include include include include define maxn 2005 using namespace std typedef...