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.
有一个序列,题目用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.
相关文章推荐
- 测试开发之----给你的apk加上时间分片的log记录
- Android Volley完全解析(一),初识Volley的基本用法
- 第一个linux驱动_读写设备文件(1)
- 数据库读写分离
- POJ 3371
- 一个简单的逆向
- 在ubuntu电脑上使用C语言编写Android应用程序
- Python爬虫爬取百度图片
- leetcode16:3Sum Closest
- 关于JFinal拦截器的理解
- 基本概念学习(2002)---指令周期
- 慕课网javascript 进阶篇 第九章 编程练习
- poj_3159_Candies
- LintCode : 最长公共前缀
- Leetcode1.Two Sum+LeetCode15.3Sum+LeetCode18. 4Sum【K-Sum问题】
- 装载问题ACC pascal程序
- 500 G JAVA视频网盘分享
- Linux命令介绍
- pyqt4简易的计算器
- [入门训练] 圆的面积