单纯形 BZOJ3112: [Zjoi2013]防守战线
题面自己上网查。
学了一下单纯形。当然 证明什么的 显然是没去学。不然估计就要残废了
上学期已经了解了 什么叫标准型。 听起来高大上 其实没什么
就是加入好多松弛变量+各种*(-1),使得最后成为一般形式:
给定A[][],求满足A[i][j]*Xj<=A[i][0];(0<i<=n,0<j<=m)
使A[0][j]*Xj最大的X[];
如果题面中直接得出的条件是A[i][j]*Xj>=A[i][0]; 使 A[0][j]*Xj最小。
那么就要用对偶定理,变成 A[i][j]*Yi<=A[0][j] 使A[i][0]*Yi最大
(实际上只要把A转置一下就好了)
才写了两题单纯形,具体的怎么求Xi之类的 还没学,这里先放代码,之后再补
#include <bits/stdc++.h>
#define N 1005
#define M 10005
using namespace std;
const double eps=0.00000000001;
const double inf=;
double a[N][M]; int n,m,x,y;
void simplex(){
while (){
int x=,y=; double mn=inf,t;
for (int i=;i<=m;++i) if (a[][i]>eps) {y=i; break;} //找一个可以使答案增加的xi 只要系数为正就可以
if (!y) return; //没有了 说明答案已经不能再增加了
for (int i=;i<=n;++i) if (a[i][y]>eps&&a[i][]/a[i][y]<mn) mn=a[x=i][]/a[i][y]; //对找到的xi ,求出约束最紧的一条约束
if (!x) {a[][]=-inf; return;} //表示 可以无限增加
t=a[x][y]; a[x][y]=;
for (int i=;i<=m;++i) a[x][i]/=t;
for (int i=;i<=n;++i) if (i!=x&&abs(a[i][y])>eps){
t=a[i][y]; a[i][y]=; for (int j=;j<=m;++j) a[i][j]-=t*a[x][j];
}
}
}
int main(){
scanf("%d%d",&n,&m);
for (int i=;i<=n;++i) scanf("%lf",&a[i][]);
for (int i=;i<=m;++i){
scanf("%d%d%lf",&x,&y,&a[][i]);
for (int j=x;j<=y;++j) ++a[j][i];
}
simplex();
printf("%.0lf",round(-a[][]));
return ;
}
好短啊
18年来补。
UOJ的板子题。。应该比较科学了(忽略中间那个assert)
。还有就是 ,单纯形真的不靠谱,,还要random才能过?。。
#include <bits/stdc++.h>
#define DB long double
using namespace std;
const DB eps=0.000000001;
int n,m,T,k,t,o[],c[];
DB tmp[],a[][];
void SWAP(int k,int t){
swap(o[k],c[t]);
DB x=a[k][t]; a[k][t]=;
for (int j=;j<=n;++j) a[k][j]/=x;
for (int i=;i<=m;++i)
if (i!=k){
x=a[i][t]; a[i][t]=;
for (int j=;j<=n;++j) a[i][j]-=x*a[k][j];
}
}
int main(){
scanf("%d%d%d",&n,&m,&T);
for (int i=;i<=n;++i) scanf("%Lf",&tmp[i]);
for (int i=;i<=n;++i) c[i]=i;
for (int i=;i<=m;++i){
for (int j=;j<=n;++j) scanf("%Lf",&a[i][j]);
scanf("%Lf",&a[i][]); o[i]=i+n;
}
k=-;
for (int i=;i<=m;++i)
if (a[i][]<&&(k==-||a[i][]<a[k][])) k=i;
if (~k){
++n; c[n]=n+m;
for (int i=;i<=m;++i) a[i][n]=-;
SWAP(k,n);
while (){
t=-;
for (int j=n;j;--j)
if (a[][j]>eps) {t=j; if (rand()&) break;}
if (t==-) break;
k=-;
for (int i=;i<=m;++i)
if (a[i][t]>eps)
if (k==-||a[i][]/a[i][t]<a[k][]/a[k][t]) k=i;
SWAP(k,t);
}
if (fabs(a[][])>eps){
puts("Infeasible"); return ;
}
k=t=-;
for (int i=;i<=n;++i) if (c[i]==n+m) t=i;
for (int i=;i<=m;++i) if (o[i]==n+m) k=i;
if (~k){
for (int j=;j<=n;++j)
if (fabs(a[k][j])>eps) {t=j; break;}
if (t==-){
assert(); swap(o[k],o[m]);
for (int j=;j<=n;++j) swap(a[k][j],a[m][j]);
--m;
}else{
SWAP(k,t); swap(c[t],c[n]);
for (int i=;i<=m;++i) swap(a[i][t],a[i][n]);
--n;
}
}else{
swap(c[t],c[n]);
for (int i=;i<=m;++i) swap(a[i][t],a[i][n]);
--n;
}
}
for (int i=;i<=n;++i) a[][i]=;
for (int i=;i<=n;++i)
if (c[i]<=n) a[][i]+=tmp[c[i]];
for (int i=;i<=m;++i)
if (o[i]<=n)
for (int j=;j<=n;++j)
a[][j]-=tmp[o[i]]*a[i][j];
while (){
t=-;
for (int j=n;j;--j)
if (a[][j]>eps) {t=j; if (rand()&) break;}
if (t==-) break;
k=-;
for (int i=;i<=m;++i)
if (a[i][t]>eps)
if (k==-||a[i][]/a[i][t]<a[k][]/a[k][t]) k=i;
if (k==-){
puts("Unbounded");
return ;
}
SWAP(k,t);
}
printf("%.10Lf\n",-a[][]);
if (T){
for (int i=;i<=n;++i) tmp[c[i]]=;
for (int i=;i<=m;++i) tmp[o[i]]=a[i][];
for (int i=;i<=n;++i) printf("%.10Lf ",tmp[i]);
puts("");
}
return ;
}
天壌を翔る者たち
单纯形 BZOJ3112: [Zjoi2013]防守战线的更多相关文章
- BZOJ3112 [Zjoi2013]防守战线 【单纯形】
题目链接 BZOJ3112 题解 同志愿者招募 费用流神题 单纯形裸题 \(BZOJ\)可过 洛谷被卡.. #include<algorithm> #include<iostream ...
- bzoj3112 [Zjoi2013]防守战线
正解:线性规划. 直接套单纯形的板子,因为所约束条件都是>=号,且目标函数为最小值,所以考虑对偶转换,转置一下原矩阵就好了. //It is made by wfj_2048~ #include ...
- bzoj3550: [ONTAK2010]Vacation&&bzoj3112: [Zjoi2013]防守战线
学了下单纯形法解线性规划 看起来好像并不是特别难,第二个code有注释.我还有...*=-....这个不是特别懂 第一个是正常的,第二个是解对偶问题的 #include<cstdio> # ...
- 【BZOJ3112】[Zjoi2013]防守战线 单纯形法
[BZOJ3112][Zjoi2013]防守战线 题解:依旧是转化成对偶问题,然后敲板子就行了~ 建完表后发现跟志愿者招募的表正好是相反的,感觉很神奇~ #include <cstdio> ...
- BZOJ 3112 Zjoi2013 防守战线 单纯形
题目大意: 单纯形*2.. . #include <cmath> #include <cstdio> #include <cstring> #include < ...
- ZJOI2013 防守战线
题目 战线可以看作一个长度为\(n\)的序列,现在需要在这个序列上建塔来防守敌兵,在序列第\(i\)号位置上建一座塔有\(C_i\)的花费,且一个位置可以建任意多的塔,费用累加计算.有\(m\)个区间 ...
- BZOJ 3112: [Zjoi2013]防守战线 [单纯形法]
题目描述 战线可以看作一个长度为n 的序列,现在需要在这个序列上建塔来防守敌兵,在序列第i 号位置上建一座塔有Ci 的花费,且一个位置可以建任意多的塔,费用累加计算.有m 个区间[L1, R1], [ ...
- BZOJ 3112 [Zjoi2013]防守战线
题解:单纯形:转化为对偶问题: 对于最大化 cx,满足约束 Ax<=b ,x>0 对偶问题为 最小化 bx,满足约束 ATx>=c ,x>0 (AT为A的转置) 这一题的内存真 ...
- 数学(线性规划): ZJOI2013 防守战线
偷懒用的线性规划. #include <iostream> #include <cstring> #include <cstdio> using namespace ...
随机推荐
- Linux基础之vi编辑器(二)
vi 编辑器 man vim 一 打开文件,定义光标 vi +# test 打开文件,定位于#行.vi + test 打开test文件,定位于最后一行.vi +/patter ...
- CPU问题定位与解决
CPU问题定位基本流程: 性能计数器诊断 主要用到的性能计数器 %Process Time 全实例 (主要用于查看当前服务器的CPU 情况) %Process Time sqlservr (主要用 ...
- 怎么删除"自豪地采用WordPress"
wordpress刚刚安装完毕,打开默认的主页,会发现底部有这样的一行文字:“自豪地采用WordPress”.当然了,我们做一个网站,不一定需要这些文字,我们可以删除或者修改这些文字.今天,小编就来教 ...
- java 读取数据库数据转化输出XML输出在jsp页面
因为老师实验报告要求,搭建服务端解析XML 下面代码实现转化XML格式也是在网上找的转化代码 输出在jsp页面以便于客户端解析是自己写的 一个类就解决了Test package tests; //三只 ...
- vmware下centos6.7网络配置
使用NAT方式: 查看/etc/sysconfig/network-script/ 下面没有ifcfg-eth0 新建ifcfg-eth0,内容如下 DEVICE=eth0 BOOTPROTO=dhc ...
- cmd的操作命令导出导入.dmp文件
利用cmd的操作命令导出,详情如下(备注:方法二是转载网上的教程): 1:G:\Oracle\product\10.1.0\Client_1\NETWORK\ADMIN目录下有个tnsname.ora ...
- flask-admin的学习使用
参考: 1.https://blog.igevin.info/wechats/wechat-flask-admin/ 2.http://flask-admin.readthedocs.io/en/la ...
- 【c++】面向对象程序设计之访问控制与继承
受保护的成员(protected): 1.和私有成员类似,受保护的成员对于类的用户来说是不可访问的 2.和共有成员类似,受保护的成员对于派生类的成员和友元来说是可访问的 3.派生类的友元只能通过派生类 ...
- 【转载】C# 装箱和拆箱[整理]
1. 装箱和拆箱是一个抽象的概念 2. 装箱是将值类型转换为引用类型 :拆箱是将引用类型转换为值类型 利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的 ...
- woodcut
http://www.lintcode.com/en/problem/wood-cut/# 二分答案,贪心验证,具有单调性 class Solution { public: /** *@param L ...