嗯什么是差分约束系统
就是已知一组条件
x1-x2<=m1
xi-xj<=mp;
......
然后让你求x1-xn的最大值
ans:
构图
构造x1,x2......xn n个点
x1,x2之间连权为m1的边
xi,xj之间连权为mp的边
......
求x1到xn的最短路就可以了
如果有x1-x2>=m1或者x1-x2<m1什么奇怪的条件就把它转化一下就好了
//通常会和前缀和什么的一起乱搞搞
Vijos 区间
描述
对于一个整数序列,给出的一个三元组[a,b,c]表示该序列在闭区间[a,b]的整数至少有c个,其中a,b,c均为整数。
题目将给出n个三元组,求同时满足这n个三元组的序列的最少元素个数是多少。如果不存在这样的满足要求的序列,则输出-1。
然后就是a..b里有c个数就是s[b]-s[a-1]>=c;
然后就构造差分约束系统
然后注意a可能会取到0
所以把整个数轴向左移(即读入的时候把a,b+1)来做
Code://用的是没加优化的SPFA 跑的飞起,加了优化反而TLE
const INF=1 shl 20;
var d,headlist:array[0..50001] of longint;
t,weight,next:array[0..5000001] of longint;
vis:array[0..50001] of boolean;
queue:array[0..10000001] of longint;
x,a,b,c,num,i,j,k,n,tot,front,finish:longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a);
exit(b);
end;
procedure addedge(x,y,z:longint);
begin
inc(num);
next[num]:=headlist[x];
headlist[x]:=num;
t[num]:=y;
weight[num]:=z;
end;
procedure GotTu;
begin
for i:=0 to 50001 do headlist[i]:=-1;
for i:=0 to 50001 do d[i]:=INF;
fillchar(vis,sizeof(vis),false);
readln(n);
for i:=1 to n do
begin
readln(a,b,c);
if c>b-a+1 then begin
writeln(-1);
halt;
end;
tot:=max(tot,b+1);
addedge(a,b+1,-c);
end;
for i:=1 to tot do
begin
addedge(i,i-1,1);
addedge(i-1,i,0);
end;
end;
procedure SPFA;
begin
front:=1; finish:=2;
queue[2]:=0; d[0]:=0;
while front<>finish do
begin
inc(front);
x:=queue[front];
i:=headlist[x];
while i<>-1 do
begin
if d[t[i]]>d[x]+weight[i] then begin
d[t[i]]:=d[x]+weight[i];
if not(vis[t[i]]) then begin
inc(finish);
queue[finish]:=t[i];
vis[t[i]]:=true;
end;
end;
i:=next[i];
end;
vis[x]:=false;
end;
end;
procedure main;
begin
GotTu;
spfa;
writeln(-d[tot]);
end;
begin
main;
end.