差分约束判是否有负环
设S[j]=a0+a1+a2+...+aj
由题意:S[si+ni]-S[si-1]>k或S[si+ni]-S[si-1]<k,由于差分约束系统只能解决>=和<=的情况,要把>k转换成>=k+1,<k转换成<=k-1
差分约束加入附加源点是为了保证图的连通性,但也可以不加附加源点,而是一开始把所有顶点都入队,并设dis为0(这个时候不算入队次数),相当于超级源点的权值
代码:
#include<iostream> #include<queue> #include<stack> using namespace std; const int MAX=105; const int inf=1<<30; struct node { int v,w,next; }g[MAX*MAX]; int dis[MAX],adj[MAX],vis[MAX],cnt[MAX]; int e,n,m; void add(int u,int v,int c) { g[e].v=v; g[e].w=c; g[e].next=adj[u]; adj[u]=e++; } int spfa() { int u,v,i; queue<int>que; memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); for(i=0;i<=n+1;i++) { dis[i]=0; que.push(i); vis[i]=1; } while(!que.empty()) { u=que.front(); que.pop(); vis[u]=0; for(i=adj[u];i!=-1;i=g[i].next) { v=g[i].v; if(dis[v]>dis[u]+g[i].w) { dis[v]=dis[u]+g[i].w; if(!vis[v]) { que.push(v); vis[v]=1; cnt[v]++; if(cnt[v]>n) return 0; } } } } return 1; } int main() { int i,j,c; char op[5]; while(scanf("%d",&n)!=EOF&&n) { memset(adj,-1,sizeof(adj)); e=0; scanf("%d",&m); while(m--) { scanf("%d%d%s%d",&i,&j,&op,&c); if(op[0]=='g') { add(j+i,i-1,-c-1); } else add(i-1,i+j,c-1); } if(spfa()) puts("lamentable kingdom"); else puts("successful conspiracy"); } return 0; }