单纯形的实现

烧卖的代码在这里: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出的,目测只能线性规划,但是我现在还没做完,所以以后再贴代码.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值