差分約束系統

嗯什麼是差分約束系統

就是已知一組條件

  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。

格式

輸入格式

第一行一個整數n(n<=50000),表示區間個數。

接下來n行,每行三個整數a,b,c(0<=a<=b<=50000,1<=c<=b-a+1),用一個空格隔開,意義如題目描述。

輸出格式

一個數,即爲答案

樣例

樣例輸入

5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1

樣例輸出

6

限制

每個測試點1s

提示

由於官方數據不全,所以有幾個點是自己做的
樣例說明:
滿足條件的最少元素序列:3,4,5,8,9,10
[3,7]中有3,4,5三個數
[8,10]中有8,9,10三個數
……

用一個前綴和s[i]表示從1..i中有幾個選進來

然後就是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.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章