poj 1364

这个题目英文太难了 , 看了半天都没看懂 , 不知道是不是老外出的题 。
其实这就是一个差分约束的题目 。
意思:给出一个系列 S1、S2、S3、S4...... , 然后给出三个数s、n、k和一个表示是大于还是等于的字符串 ,问:Ss + Ss+1 + .....+Ss+n 能不能满足题目要求和k的关系 。

所以有关图的题目 , 最重要的就是能 , 分析出题目给的各个之间的关系 , 然后再通过这些关系来建图 。
Ss + Ss+1 + .....+Ss+n = SUM(s+n) - SUM(s-1) ; SUM表示从1到s+n系列的和 。
如果是: Ss + Ss+1 + .....+Ss+n > k 则  SUM(s-1) - SUM(s+n) <= -k-1;
如果是: Ss + Ss+1 + .....+Ss+n < k 则  SUM(s+n) - SUM(s-1) <= k-1;
现在就可以看过是差分约束系统了 。

要注意的一点是:差分系统只能满足<= 这种情况 。

代码:
#include
#include
#include
#include
#include
#include
using namespace std;

const int MAXN = 110;
const int INF = 0x3f3f3f3f;
vectoredge[MAXN] ;
int d[MAXN] , n , m;
int grap[MAXN][MAXN];

void init()
{
      for(int i = 0 ; i <= n+1; i++)
            edge[i].clear();
      memset(grap , 0 , sizeof(grap));
}

bool bellman_ford(int s)
{
      int i , bz[MAXN] , maxsum[MAXN];
      memset(bz , 0 , sizeof(bz));
      memset(maxsum , 0 , sizeof(maxsum));
      for(i = 0; i <= n+1; i++)  d[i] = INF;
      d[s] = 0;
      queueq;
      q.push(s);  bz[s] = 1;  maxsum[s]+=1;
      while(!q.empty())
      {
            int u = q.front() ; q.pop() ;  bz[u] = 0;
            for(i = 0 ; i < edge[u].size() ; i++)
            {
                  int v = edge[u][i];
                  if(d[v] > d[u]+grap[u][v])
                  {
                        d[v] = d[u] + grap[u][v];
                        if(!bz[v])
                        {
                              if(++maxsum[v] > (n+2))  return false;
                              q.push(v);
                              bz[v] = 1;
                        }
                  }
            }
      }
      return true;
}

int main()
{
      while(scanf("%d" , &n ) && n)
      {
            init();
            scanf("%d" , &m);
            int i , x , y , dist;
            char c[3];
            for(i = 1; i <= m; i++)
            {
                  scanf("%d %d %s %d" , &x , &y , c ,&dist);
                  if(strcmp(c , "gt") == 0)
                  {
                        //printf("%d , %d" , x , y);
                        edge[x+y].push_back(x-1);
                        grap[x+y][x-1] = -dist-1;
                  }
                  else
                  {
                        edge[x-1].push_back(x+y);
                        grap[x-1][x+y] = dist-1;
                  }
            }
            for(i = 1; i <= n; i++)
                  edge[n+1].push_back(i);
            bool bz = bellman_ford(n+1);
            if(bz)  printf("lamentable kingdom\n");
            else printf("successful conspiracy\n");
      }
      return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值