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 ;
}
View Code

 

posted on 2013-12-06 22:08  枫、  阅读(173)  评论(0编辑  收藏  举报