例题
https://www.luogu.org/problemnew/show/P3385
说明一下,这个例题用下面的方法是过不了的,只能过掉25分因为数据加强了,而我不会写BFS版SPFA判负环
但是我觉得会DFS版的就行了,反正对于随机数据DFS版的绝对吊打BFS版的
只不过这道题的数据不是随机的,是有人恶意添加的
坑点
- hint中已经提到的建议粘贴输出的字符串,因为是YE‘5’,而不是‘S’,是N‘0’,而不是O(统统毒瘤)
- 图不一定是联通的,是不是很强,这更让我们感受到了世界的敌意
- 如果要判负环的话,对于最短路的部分,我们就可以舍弃掉一部分了,dis=0额不是dis=INF因为这样可以最大程度的优化程序,将最短路的求解部分弱化
思路
我们利用DFS强行进行松弛操作(我感觉已经不能叫他SPFA了)
如果在一条路径上一个点被重复访问过了,那就是说明出现了负环
输出YE5就行了
代码
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> const int maxnode = 2007; const int maxedge = 3007*2; using namespace std; int x, f; char c; inline int read() { x = 0, f = 1; c = getchar(); while (c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = x*10 + c-'0'; c = getchar(); } return x * f; } int T, n, m, u[maxedge], v[maxedge], w[maxedge]; int first[maxnode], nur[maxedge], dis[maxnode]; bool vis[maxnode], book; inline void addedge(int f, int i) { nur[i] = first[f]; first[f] = i; } int k; inline void SPFA(int s) { if(book) return ; vis[s] = 1; k = first[s]; while (k != -1) { if(book) return ; if(dis[v[k]] > dis[u[k]] + w[k]) { dis[v[k]] = dis[u[k]] + w[k]; if(vis[v[k]]) book = 1; else SPFA(v[k]); } k = nur[k]; } vis[s] = 0; } int main() { T = read(); while (T--) { n = read(), m = read(); book = 0; memset(first, -1, sizeof(first)); memset(vis, 0, sizeof(vis)); memset(dis, 0, sizeof(dis)); memset(nur, -1, sizeof(nur)); for(int i=1; i<=m*2; i++) { u[i] = v[i+1] = read(); v[i] = u[i+1] = read(); w[i] = w[i+1] = read(); addedge(u[i], i); i++; if(w[i] >= 0) { addedge(u[i], i); } } for(int i=1; i<=n&&!book; i++) SPFA(i); (book)?(puts("YE5")):(puts("N0")); } return 0; }