您的位置:首页 > 其它

POJ 1201 Intervals 差分约束系统

2016-12-02 20:16 337 查看
题目:

有一个序列,题目用n 个整数组合[ai,bi,ci]来描述它,[ai,bi,

ci]表示在该序列中处于[ai,bi]这个区间的整数至少有ci 个。如果存在这样的序列,请求

出满足题目要求的最短的序列长度是多少。如果不存在则输出-1。

输入:第一行包括一个整数n,表示区间个数,以下n 行每行描述这些区间,第i+1 行

三个整数ai,bi,ci,由空格隔开,其中0<=ai<=bi<=50000 而且1<=ci<=bi-ai+1。

输出:一行,输出满足要求的序列的长度的最小值。

输入样例:

53

7 3

8 10 3

6 8 1

1 3 1

10 11 1

输出样例:

6

分析:

线性函数,其实是可以转化为单源最短路径问题,从而用刚才所准备到的Bellman Ford算法来解决它。

代码:

const

  maxn=150000;

type

  node=record

    fromv,endv,value:longint;

  end;

var

  data:array[0..maxn] of longint;

  elist:array[0..maxn] of node;

  n,m,max,min:longint;

procedure add(x,y,z:longint);

begin

  inc(m);

  with elist[m] do

    begin

      fromv:=x;

      endv:=y;

      value:=z;

    end;

end;

procedure init;

var

  i,x,y,z:longint;

begin

  readln(n);

  m:=0;max:=0;min:=maxlongint;

  for i:=1 to n do

    begin

      readln(x,y,z);

      dec(x);

      add(y,x,-z);

      if max<y then

        max:=y;

      if min>x then

        min:=x;

    end;

  for i:=min+1 to max do

    begin

      add(i-1,i,1);

      add(i,i-1,0);

    end;

end;

procedure main;

var

  i:longint;

  check:boolean;

begin

  for i:=min to max do

    data[i]:=100000;

  while true do

    begin

      check:=true;

      for i:=1 to m do

        with elist[i] do

         if data[endv]>data[fromv]+value then

           begin

             data[endv]:=data[fromv]+value;

             check:=false;

           end;

      if check then

        break;

    end;

  writeln(data[max]-data[min]);

end;

begin

  init;

  main;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: