单纯形 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 ...
随机推荐
- Python的3种格式化字符串方法
Python中有3种format字符串的方式: 传统C语言式 命名参数 位置参数 1. 传统C语言式 和c语言里面的 sprintf 类似,参数格式也一样 title = "world&qu ...
- AR+ 实时音视频通话,虚拟与现实无缝结合
今年中旬 Google 在万众期待下推出了 ARCore,能将现实与数码完美无缝地融合在一起,丰富我们的现实世界.通过它开发者可以更加快速方便地在 Android 平台开发 AR 应用,凭借 AR 技 ...
- bzoj1004 [HNOI2008]Cards 置换群+背包
[bzoj1004][HNOI2008]Cards 2014年5月26日5,3502 Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿 ...
- 关于系统中使用多个PropertyPlaceholderConfigurer的配置
多数的鲜为人知方法都是因为有着罕见的应用,就比如说Spring中PropertyPlaceholderConfigurer这个类,它是用来解析Java Properties属性文件值,并提供在spri ...
- 搭建双塔(vijos 1037)
描述 2001年9月11日,一场突发的灾难将纽约世界贸易中心大厦夷为平地,Mr. F曾亲眼目睹了这次灾难.为了纪念“9?11”事件,Mr. F决定自己用水晶来搭建一座双塔. Mr. F有N块水晶,每块 ...
- BZOJ1777: [Usaco2010 Hol]rocks 石头木头
n<=10000的树,节点有初始石头数<=1000,进行这样的游戏:两人轮流行动,我先手,每次可以选一个节点(≠1)把不超过m<=1000个石头移到父亲,最后所有石头都在节点1,没法 ...
- hihoCoder #1014 : Trie树 [ Trie ]
传送门 #1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互 ...
- Codeforces Round #295 D. Cubes [贪心 set map]
传送门 D. Cubes time limit per test 3 seconds memory limit per test 256 megabytes input standard input ...
- Python()- 面向对象的组合用法
面向对象的组合用法 一个类中以另一个类的对象作为数据属性(一个类中引用另一个类的对象)一种 "有" 的关系: 比如:定义 1个人类 & 1个武器类 然后 张三 有 枪 李四 ...
- Codeforces 703C(计算几何)
C. Chris and Road time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...