以前用差分约束以为只能求可行解,没想到跟上下界网络流一样能求最优解。
题意:在[1,50000]中选取一系列整点是满足一系列不等式,在[a,b]中至少有c个整点,要求选取的整点数最少。
先说最优解问题:
1、最小解:
将初值赋为最小,利用松弛条件:d[u]+w[u,v]>=d[v]修改(使满足条件的值是最小的),于是连边条件为d[v]-d[u]>=w[u,v]。
2、最大解:
将初值赋为最大,利用松弛条件:d[u]+w[u,v]<=d[v]修改(使满足条件的值是最大的),于是连边条件为d[v]-d[u]<=w[u,v]。
针对此题目有几个不等式需分析出来:
1、S[b]-S[a-1]>=c(题目条件)
2、1>=S[I]-S[I-1]>=0(保证是整点且递增)
由2推出 a、S[I-1]-S[I]>=-1(由上式变形为求最小解的不等式)
b、S[I]-S[I-1]>=0
建图,spfa即可过之。一开始不必建超级源点,只需将所有点入队。
const maxn=50000;maxm=1100000; var d,tail:array[0..maxn]of longint; v:array[0..maxn]of boolean; st,next,sora,cost:array[0..maxm]of longint; n,ss:longint; procedure link(x,y,z:longint); begin inc(ss);next[tail[x]]:=ss;tail[x]:=ss;sora[ss]:=y;cost[ss]:=z end; procedure spfa; var i,ne,na,h,r:longint; begin fillchar(st,sizeof(st),0); h:=0;r:=1;st[1]:=maxn; for i:=0 to maxn-1 do begin inc(r);st[r]:=i; link(i+1,i,-1);link(i,i+1,0) end; fillchar(d,sizeof(d),0);fillchar(v,sizeof(v),false); repeat inc(h);ne:=st[h]; i:=ne; while next[i]<>0 do begin i:=next[i];na:=sora[i]; if d[ne]+cost[i]>d[na] then begin d[na]:=d[ne]+cost[i]; if v[na] then begin v[na]:=false; inc(r);st[r]:=na end end end; v[ne]:=true until h>=r end; procedure origin; var i:longint; begin fillchar(tail,sizeof(tail),0); for i:=0 to maxn do tail[i]:=i;ss:=maxn end; procedure init; var i,x,y,z:longint; begin readln(n); origin; for i:=1 to n do begin readln(x,y,z); link(x-1,y,z) end; spfa; writeln(d[maxn]) end; begin assign(input,'1201.in');reset(input); init; close(input) end.