BZOJ_1027_[JSOI2007]_合金_(计算几何+Floyd求最小环)
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=1027
共三种金属,\(m\)种材料,给出每种材料中三种金属的占比.
给出\(n\)种合金的三种金属占比.用材料做合金,问最少需要多少种材料.
分析
首先,由于三种金属的占比相加为1,所以确定了前两项,最后一项也就确定了,我们可以用二唯坐标\((x,y)\)表示前两项,这样每种材料和合金就是二维平面上的一个点.
接下来是用材料做合金.
首先来考虑用两种材料做合金,两种材料为\((x1,y1)和(x2,y2)\).那么做成的合金就是\((kx1+(1-k)x2,ky1+(1-k)y2) ,0\leq{k}\leq1\).
记两种材料为两个向量\(\overrightarrow{a},\overrightarrow{b}\),那么合金就是$$k\overrightarrow{a}+(1-k)\overrightarrow{b}$$
等于$$k\overrightarrow{a}+(1-k)\overrightarrow{a}+(1-k)(\overrightarrow{b}-\overrightarrow{a})$$
也就是说合金的点在两个材料的点所连的线段上.
那么对于多个材料,我们把几个材料的点首尾相连,形成一个凸多边形,多边形内部的任意一点可以认为是在(多边形的两条边上的点所连的线段上),我们把那两个点做出来当作材料,就可以做出来多边形内部的点了.而多边形外部的点不在可做成的两点所连的线段上.
如果连成的是凹多边形呢?可以去掉一些材料变成材料种类更少的凸多边形.
所以就要把所有合金放在材料围成的多边形内部(或边上).我们把所有点都在同一侧的线段连一条长度为1的边,然后问题就转化为了求最小环,用Floyd即可.
注意:特殊情况,即所有合金都与一个材料重合,此时答案是1.其他情况全部可以一般化.
#include <bits/stdc++.h>
using namespace std; const int maxn=+;
const double eps=1e-,INF=<<;
int n,m;
int d[maxn][maxn];
inline int dcmp(double x){
if(fabs(x)<eps) return ;
return x>?:-;
}
struct pt{
double x,y;
pt(double x=,double y=):x(x),y(y){}
pt operator - (const pt &a) const { return pt(x-a.x,y-a.y); }
double operator * (const pt &a) const { return x*a.y-y*a.x; }
double operator ^ (const pt &a) const { return x*a.x+y*a.y; }
bool operator != (const pt &a) const { return (dcmp(a.x-x)||dcmp(a.y-y)); }
}a[maxn],b[maxn];
inline bool spj(){
for(int i=;i<=m;i++){
bool flag=true;
for(int j=;j<=n;j++)if(a[i]!=b[j]){
flag=false;
break;
}
if(flag) return true;
}
return false;
}
inline bool J(pt p1,pt p2){
for(int i=;i<=n;i++)if(dcmp((b[i]-p1)^(b[i]-p2))>) return false;
return true;
}
inline int C(pt p1,pt p2){
int l=,r=;
for(int i=;i<=n;i++){
double t=(p2-p1)*(b[i]-p1);
if(dcmp(t)>) l++;
else if(dcmp(t)<) r++;
if(l&&r) return ;
}
if(!l&&!r&&J(p1,p2)) return ;
if(l) return ;
if(r) return ;
return ;
}
inline void floyd(){
for(int k=;k<=m;k++)for(int i=;i<=m;i++)for(int j=;j<=m;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
int ans=INF;
for(int i=;i<=m;i++) ans=min(ans,d[i][i]);
if(ans==INF){ puts("-1"); return; }
printf("%d\n",ans);
}
inline void solve(){
if(spj()){ puts(""); return; }
for(int i=;i<=m;i++)for(int j=i+;j<=m;j++){
int flag=C(a[i],a[j]);
if(flag==) d[i][j]=;
else if(flag==) d[j][i]=;
else if(flag==) d[i][j]=d[j][i]=;
}
floyd();
}
inline void init(){
scanf("%d%d",&m,&n); double t;
for(int i=;i<maxn;i++)for(int j=;j<maxn;j++) d[i][j]=INF;
for(int i=;i<=m;i++) scanf("%lf%lf%lf",&a[i].x,&a[i].y,&t);
for(int i=;i<=n;i++) scanf("%lf%lf%lf",&b[i].x,&b[i].y,&t);
}
int main(){
init();
solve();
return ;
}
1027: [JSOI2007]合金
Time Limit: 4 Sec Memory Limit: 162 MB
Submit: 3382 Solved: 955
[Submit][Status][Discuss]
Description
某公司加工一种由铁、铝、锡组成的合金。他们的工作很简单。首先进口一些铁铝锡合金原材料,不同种类的
原材料中铁铝锡的比重不同。然后,将每种原材料取出一定量,经过融解、混合,得到新的合金。新的合金的铁铝
锡比重为用户所需要的比重。 现在,用户给出了n种他们需要的合金,以及每种合金中铁铝锡的比重。公司希望能
够订购最少种类的原材料,并且使用这些原材料可以加工出用户需要的所有种类的合金。
Input
第一行两个整数m和n(m, n ≤ 500),分别表示原材料种数和用户需要的合金种数。第2到m + 1行,每行三
个实数a, b, c(a, b, c ≥ 0 且 a + b + c = 1),分别表示铁铝锡在一种原材料中所占的比重。第m + 2到m +
n + 1行,每行三个实数a, b, c(a, b, c ≥ 0 且 a + b + c = 1),分别表示铁铝锡在一种用户需要的合金中
所占的比重。
Output
一个整数,表示最少需要的原材料种数。若无解,则输出–1。
Sample Input
0.1 0.2 0.7
0.2 0.3 0.5
0.3 0.4 0.3
0.4 0.5 0.1
0.5 0.1 0.4
0.6 0.2 0.2
0.7 0.3 0
0.8 0.1 0.1
0.9 0.1 0
1 0 0
0.1 0.2 0.7
0.2 0.3 0.5
0.3 0.4 0.3
0.4 0.5 0.1
0.5 0.1 0.4
0.6 0.2 0.2
0.7 0.3 0
0.8 0.1 0.1
0.9 0.1 0
1 0 0
Sample Output
HINT
Source
BZOJ_1027_[JSOI2007]_合金_(计算几何+Floyd求最小环)的更多相关文章
- BZOJ 1027: [JSOI2007]合金 (计算几何+Floyd求最小环)
题解就看这位仁兄的吧-不过代码还是别看他的了- 同样的方法-我200ms,他2000ms. 常数的幽怨- CODE #include <bits/stdc++.h> using names ...
- 弗洛伊德Floyd求最小环
模板: #include<bits/stdc++.h> using namespace std; ; const int INF = 0xffffff0; ]; void Solve(in ...
- 【BZOJ 1027】 (凸包+floyd求最小环)
[题意] 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金 ...
- 2017"百度之星"程序设计大赛 - 资格赛【1001 Floyd求最小环 1002 歪解(并查集),1003 完全背包 1004 01背包 1005 打表找规律+卡特兰数】
度度熊保护村庄 Accepts: 13 Submissions: 488 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3276 ...
- Floyd求最小环!(转载,非原创) 附加习题(原创。)HDU-1599
//Floyd 的 改进写法可以解决最小环问题,时间复杂度依然是 O(n^3),储存结构也是邻接矩阵 int mincircle = infinity; Dist = Graph; ;k<nVe ...
- 2018.09.15 hdu1599find the mincost route(floyd求最小环)
传送门 floyd求最小环的板子题目. 就是枚举两个相邻的点求最小环就行了. 代码: #include<bits/stdc++.h> #define inf 0x3f3f3f3f3f3f ...
- 算法复习——floyd求最小环(poj1734)
题目: 题目描述 N 个景区,任意两个景区之间有一条或多条双向的路来连接,现在 Mr.Zeng 想找一条旅游路线,这个路线从A点出发并且最后回到 A 点,假设经过的路线为 V1,V2,....VK,V ...
- floyd求最小环 模板
http://www.cnblogs.com/Yz81128/archive/2012/08/15/2640940.html 求最小环 floyd求最小环 2011-08-14 9:42 1 定义: ...
- CF 1206D - Shortest Cycle Floyd求最小环
Shortest Cycle 题意 有n(n <= 100000)个数字,两个数字间取&运算结果大于0的话连一条边.问图中的最小环. 思路 可以发现当非0数的个数很大,比如大于200时, ...
随机推荐
- 3、WPF学习之-布局
一.基础知识 1.所有WPF布局容器都派生自System.Windows.Controls.Panel抽象类的面板: 2.WPF种核心布局面板有StackPanel(栈面板).WrapPanel(环绕 ...
- mac 下 sphinx + mysql + php 实现全文搜索(xampp)(3)sphinx 的配置项解析
source:数据的来源,数据是从什么地方来的. index:索引,当有数据源之后,从数据源处构建索引.索引实际上就是相当于一个字典检索.有了整本字典内容以后,才会有字典检索. searchd:提供搜 ...
- MVC使用的MetaModel代码生成器模板
代码生成器能使从一些重复的工作中缓解下来 在最近开发MVC项目中使用到了MetaModel用来设定Model的显示名称,数据限制的代码生成模板,自己第一做代码生成模板还有很多缺陷. 下面是模板代码: ...
- 我的WebX框架学习总结与心得分享
最近学习了webx框架, 利用博客园跟大家分享一下自己的学习心得; 周建旭 2014-08-21 网上关于webx的资料少的可怜, 怎么办? 这种情况下不用去求助别人求人只会耽误时间, 不用畏惧; ...
- windows server 2008 r2电脑历史操作记录
1.看计算机哪天运行过. 在系统盘下的Windows\Tasks文件夹下找到文件SCHEDLGU.TXT. 2.看你最近打开过什么文件(非程序)或者文件夹 开始-->运行--> ...
- iOS 支付宝应用(备用参考2)
接入前期准备工作包括商户签约和密钥配置 步骤1: 启动IDE(如Xcode),把iOS包中的压缩文件中以下文件拷贝到项目文件夹下, 并导入到项目工程中. AlipaySDK.bundle Al ...
- IOS项目集成ShareSDK实现第三方登录、分享、关注等功能(备用)
(1)官方下载ShareSDK iOS 2.8.8,地址:http://sharesdk.cn/ (2)根据实际情况,引入相关的库,参考官方文档. (3)在项目的AppDelegate中一般情况下有三 ...
- Windows 7下载
原版的ISO:windows 7 旗舰版:32位: ed2k://|file|cn_windows_7_ultimate_x86_dvd_x15-65907.iso|2604238848|D6F139 ...
- bnu 4351 美女来找茬(水水)
http://www.bnuoj.com/bnuoj/problem_show.php?pid=4351 [题意]:用最小的矩形框,框住像素点差超过5的点. [题解]:求坐标x,y最大最小值 [cod ...
- 1031: [JSOI2007]字符加密Cipher - BZOJ
Description喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: ...