题意:给定你一些不等式组,判定不等式组是否有解。
分析:对给出的不等式组建立差分约束系统,因为差分约束只能处理>= or <= 这样的不等式,所以我们首先要将不等式转化。若oi=gt,则s[u-1] - s[u+v] <= -k-1,若oi = lt,则s[u+v] - s[u-1] <= k-1,将这些条件都转化为边后,我们还需添加一个源点,将它与所有顶点添加一条权值为0的边,以便我们求单源最短路径。为了减少边的存储,spfa初始化时,将dist[i]赋值为0,并将所有顶点添加进入队列。
spfa代码:
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int inf = 100000000;
const int maxn = 105;
struct edge{
int v,w;
int next;
edge(){};
};
int n,m;
int list[maxn];
int dist[maxn];
bool inq[maxn];
int cnt[maxn];
edge a[maxn];
void add_edge(int index, int u, int v, int w){
a[index].v = v;
a[index].w = w;
a[index].next = list[u];
list[u] = index;
}
bool input(){
scanf("%d",&n);
if(n == 0) return false;
scanf("%d",&m);
int u,v,w;
char op[5];
//clear
for(int i = 0; i < maxn; i++) list[i] = -1;
for(int i = 0; i < m; i++){
scanf("%d%d%s%d",&u,&v,&op,&w);
if(op[0] == 'g'){
add_edge(i,u+v,u-1,-w-1);
}
else{
add_edge(i,u-1,u+v,w-1);
}
}
return true;
}
bool spfa(){
queue<int> q;
for(int i = 0; i <= n; i++){
dist[i] = 0;//从源点走到所有点
q.push(i);
inq[i] = true;
cnt[i] = 1;
}
while(!q.empty()){
int u = q.front(); q.pop(); inq[u] = false;
for(int p = list[u]; p != -1; p = a[p].next){
int v = a[p].v;
int w = a[p].w;
if(dist[u] + w < dist[v]){
dist[v] = dist[u] + w;
if(!inq[v]){
q.push(v); inq[v] = true; cnt[v]++;
if(cnt[v] > n) return false;
}
}
}
}
return true;
}
int main(){
while(input()){
printf("%s\n",spfa()?"lamentable kingdom":"successful conspiracy");
}
return 0;
}