这图如果是不连通的,SPFA是会出问题的,所以可以增加一个V0的虚拟节点。

注意,题目中是>和<,要转换成>=和《=才能应用差分约束,由于是整数,是很好转换的。

得到差分约束方程:s[si+ni]-s[si-1]>=cost+1

                    s[si+ni]-s[si-1]<=cost-1  

在做SPFA时,如果存在负环则return false,表明不能满足所有的约束方程,如果不出现负权环

则可以找到这样的序列。

代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 105;
const int INF = 0x7f7f7f7f;
struct Edge
{
    
int to,dis;
    Edge *next;
};
Edge * adj[N];
Edge edges[N*2];
int n,m;
int dis[N];
bool vis[N];
int vCnt[N];
char str[10];
int cnt;
void addEdge(int s,int e,int w)
{
    Edge *ptr = &edges[cnt++];
    ptr->to = e;
    ptr->dis = w;
    ptr->next = adj[s];
    adj[s] = ptr;
}
int maxt;
bool spfa()
{
    queue <int>  Q;
    memset(vis,false,sizeof(vis));
    memset(vCnt,0,sizeof(vCnt));
    memset(dis,127,sizeof(dis));

    Q.push(0);
    vCnt[0= 1;
    dis[0= 0;
    
while(!Q.empty())
    {
        
int u =Q.front(); Q.pop();
        vis[u] = false;
        
for(Edge *ptr=adj[u];ptr;ptr=ptr->next)
        {
            
int cost = ptr->dis;
            
int v = ptr->to;
            
if(dis[v]>dis[u]+cost)
            {

                dis[v] = dis[u] + cost;
                
if(!vis[v])
                {
                    Q.push(v);
                    vCnt[v]++;
                    
if(vCnt[v]>=n+1)
                    {
                        
return false;
                    }
                    vis[v] = true;
                }
            }
        }

    }
    
return true;
}
int main()
{
    
while(scanf("%d",&n)!=EOF&&n!=0)
    {
         memset(adj,0,sizeof(adj));
        cnt = 0;
        maxt = 0;
        scanf("%d",&m);
        
for(int i=1;i<=m;i++)
        {
            
int a,b,cost;
            scanf("%d%d%s%d",&a,&b,str,&cost);
            a++;
            b = b+a;
            
if(strcmp(str,"gt")==0)
            {
                addEdge(b,a-1,-(cost+1));
            }
            
else
            {
                addEdge(a-1,b,cost-1);
            }
        }
        
for(int i=1;i<=n;i++)
        {
            addEdge(0,i,0);//增加虚拟节点
        }
        spfa() ?printf("lamentable kingdom\n") : printf("successful conspiracy\n") ;
    }
    
return 0;
}