烧卖的代码在这里:http://blog.csdn.net/jarjingx/article/details/8565910
首先我要吐槽一句:做最大流不要初始化可行解,不要判无解,不要判解无限,不要怕死循环(出题人不会卡你),怎么写都可以过.
推荐这道题目:https://icpcarchive.ecs.baylor.edu/external/40/4027.pdf,是一道三维线性规划
另外uva12512和uva12567是lrj专门为线性规划出的题目.
先给出expensive drink的代码:
{
2007 ACM/ICPC Regional Contest Expensive Drink
To Solve A Linear Programming Probleam
Simplex Method
}
type
int=longint;
real=extended;
const e=1e-9;
procedure swap(var x,y:int);var t:int;
begin t:=x;x:=y;y:=t;end;
var
i,j,k,x,y,m,n,cnt,count:int;
a:array[0..300,0..4]of real;
b,pos,ba:array[0..300]of int;
l,r,z,t,max:real;
procedure add(aa,b,c,d,e:real);
begin inc(m);a[m,0]:=aa;a[m,1]:=b;a[m,2]:=c;a[m,3]:=d;a[m,4]:=e;end;
function ok:boolean;
begin ok:=not((pos[m+4]<=m)and(abs(a[pos[m+4],0])>e))end;
procedure pivot(x,y:int);{转轴操作}
begin
swap(b[m+y],b[x]);swap(ba[m+y],ba[x]);
z:=a[x,y];a[x,y]:=-1;
for i:=0 to 4 do a[x,i]:=(-a[x,i])/z;
for i:=0 to m do if(abs(a[i,y])>e)and(x<>i)then begin
z:=a[i,y];a[i,y]:=0;
for j:=0 to 4 do a[i,j]:=a[i,j]+z*a[x,j];
end;
end;
procedure main;
var j:int=1;
begin
for i:=1 to m+4 do begin ba[i]:=-i;b[i]:=i;end;
for i:=2 to m do if(a[i,0]<a[j,0])then j:=i;
pivot(j,4);{这两行是初始化可行解}
while true do begin
j:=1;
for i:=2 to 4 do if(a[0,i]>a[0,j])
or((a[0,i]=a[0,j])and(ba[i]<ba[j]))then j:=i;
if a[0,j]<e then break;
z:=1e30;k:=0;
for i:=1 to m do if(a[i,j]<-e)then begin
t:=-a[i,0]/a[i,j];
if(t<z)or((t=z)and(ba[i+n]<ba[k+n]))then begin
z:=t;k:=i;
end;
end;
if z>1e29 then begin
write('Too expensive!!');exit;{判断解无限大}
end;
pivot(k,j);
end;
for i:=1 to m+4 do pos[b[i]]:=i;
if not ok then write('Inconsistent data'){判无解}
else write((a[0,0]+1e-9):4:4);
end;
begin
assign(input,'data.txt');reset(input);
assign(output,'main.txt');rewrite(output);
while true do begin
read(n);inc(cnt);
if n=0 then break;
write('Case ',cnt,': ');
fillchar(a,sizeof(a),0);
m:=-1;
read(l,r);
for i:=1 to n do begin
inc(m,2);
for j:=1 to 3 do read(a[m,j]);read(a[m,0]);
for j:=0 to 3 do a[m+1,j]:=-a[m,j];
a[m,0]:=-a[m,0]+r;
a[m+1,0]:=-a[m+1,0]-l;
a[m,4]:=1;a[m+1,4]:=1;
end;
inc(m);
add(0,0,-1,1,1);
add(0,-1,1,0,1);
for i:=1 to 3 do read(a[0,i]);
a[0,4]:=-1e8;a[0,0]:=r;
main;
writeln;
end;
close(output);
end.
大致的过程和烧卖的差不多,我把转轴操作写了个过程,因为要初始化可行解.
另外里面用了一个ba数组,这是给每个变量加一个标签,每次选择交换变量的时候以这个变量为第二关键字.据李宇骞说可以防止死循环,但有一个std用了这个也死循环了,不过我这个程序倒是没死循环,应该是std在其他地方有什么问题.
主过程很丑,大致的意思就是构造系数矩阵.
要注意的是,这道题目要求四位精度对单纯形来说应该太苛刻了,lrj又懒得写spj(因为正解是计算几何,精度没问题),如果用单纯形去交可能会Wa掉,用我的程序写个对拍就行了.
另外,如果你构造了一个合法数据把我的程序卡死了,请把你构造的数据发到我的邮箱2462457751@qq.com.
另外两道题目都是lrj出的,目测只能线性规划,但是我现在还没做完,所以以后再贴代码.