题意:看了题解,原来是差分约束系统的模板题,这里讲的不错点击打开链接
还有大神的体会:虽然bellman_ford不及spfa的效率,但它在判断是否存在负权回路比spfa方便。它能判断不连通的图,而spfa判断不连通图时有可能不准确,当开始的源点到达不了某些顶点时,那么那些顶点就无法检验了。为此,spfa需要添加一个超源点来使得图连通(还有一个方法:就是先把所有顶点入队)而bellman不需要添加超源点, 因为它是对图的每一条边都进行n-1次松弛。有时候超源点不好添加,这时可以考虑用bellman,按理说在SPFA算法中如果一个点重复入队超过N次的话,就确定有负环,但为了保险,我们可以判断到N+1,不然有时会出错
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <vector> using namespace std; const int MAXN = 110; const int INF = 0x3f3f3f3f; struct edge{ int v,w; edge(int a,int b){ v = a,w = b; } }; int n,m,d[MAXN],times[MAXN],inq[MAXN]; char op[MAXN]; vector<edge> g[MAXN]; bool spfa(){ queue<int> q; times[n] = 1; inq[n] = 1; q.push(n); while (!q.empty()){ int x = q.front(); q.pop(); inq[x] = 0; for (int i = 0; i < g[x].size(); i++) if (d[g[x][i].v] > d[x]+g[x][i].w){ d[g[x][i].v] = d[x] + g[x][i].w; times[g[x][i].v]++; if (times[g[x][i].v] > n+1) return false; if (!inq[g[x][i].v]){ q.push(g[x][i].v); inq[g[x][i].v] = 1; } } } return true; } int main(){ int a,b,c; while (scanf("%d%d",&n,&m) != EOF && n){ n++; memset(d,INF,sizeof(d)); memset(inq,0,sizeof(inq)); memset(times,0,sizeof(times)); d[n] = 0; g[n].clear(); for (int i = 0; i < n; i++) g[n].push_back(edge(i,0)),g[i].clear(); for (int i = 0; i < m; i++){ scanf("%d%d%s%d",&a,&b,op,&c); if (op[0] == 'g') g[a+b].push_back(edge(a-1,-c-1)); else g[a-1].push_back(edge(a+b,c-1)); } if (spfa()) puts("lamentable kingdom"); else puts("successful conspiracy"); } return 0; }