http://poj.org/problem?id=1364
题意 :给出一个序列a1,a2,a3,a4.....ai,......at ;然后给你一个不等式使得ai+a(i+1)+a(i+2)+...+a(i+n)<ki或者是ai+a(i+1)+a(i+2)+...+a(i+n)>ki,样例的意思是:gt是大于的意思,lt是小于的意思,第一个数字 i 是序列从ai 开始,第2个数字n是从ai 开始加加到an,然后最后那个数就是不等式的右边。问你所有不等式是否都满足条件,若满足输出lamentable kingdom,不满足输出successful conspiracy,
1 2 gt 0
a1+a2+a3>0
2 2 lt 2
a2+a3+a4<2
思路 :好吧,一个赤裸裸的差分。。。。转换一下首先设Si=a1+a2+a3+...+ai那么根据样例可以得出S3-S0>0---->S0-S3<=-1和S4-S1<2---->S4-S1<=1,因为差分约束的条件是小于等于,所以我们将ki-1可以得到一个等于号那么通式可以表示为
a b gt c
S[a-1]-s[a+b]<=-ki-1
a b lt c
S[a+b]-S[a-1]<=ki-1那么根据差分约束建图,加入这些有向边
gt: <a+b,a-1>=-ki-1
lt: <a-1,a+b>=ki-1
再根据bellman_ford判断是否有无负环即可
若出现负环了则这个序列不满足所有的不等式
#include <iostream> #include <stdio.h> #include <string.h> using namespace std ; struct node { int u,v,w ; } edge[150] ; int n,m,dis[150] ; int bellman() { memset(dis,0,sizeof(dis)) ; for(int i = 1 ; i <= n ; i++) for(int j = 0 ; j < m ; j++) if(dis[edge[j].u]+edge[j].w < dis[edge[j].v]) dis[edge[j].v] = dis[edge[j].u]+edge[j].w ; for(int j = 0 ; j < m ; j++) { if(dis[edge[j].u]+edge[j].w < dis[edge[j].v]) return 0 ; } return 1 ; } int main() { while(~scanf("%d",&n) && n) { scanf("%d",&m) ; int a,b,c ; char sh[3] ; for(int i = 0 ; i < m ; i++) { scanf("%d %d %s %d",&a,&b,sh,&c) ; if(sh[0] == 'g') { edge[i].u = a+b ; edge[i].v = a-1 ; edge[i].w = -c-1 ; } else { edge[i].u = a-1 ; edge[i].v = a+b ; edge[i].w = c-1 ; } } if(!bellman()) printf("successful conspiracy\n") ; else printf("lamentable kingdom\n") ; } return 0 ; }