题目大意:给定一些合金,选择最少的合金,使这些合金能够按比例合成要求的合金

首先这题的想法特别奇异 看这题干怎么会想到计算几何 并且计算几何又怎么会跟Floyd挂边 好强大

首先因为a+b+c=1 所以我们仅仅要得到a和b就可以 c=1-a-b 所以c能够不读入了

然后我们把每种原料抽象成一个点 可知两个点能合成的合金一定在两点连线的线段上

证明:设两个点为(x1,y1)和(x2,y2),新合成的合金为(ax1+bx2,ay2+by2) (a+b=1,a,b>0) 两点连线为(y-y1)/(x-x1)=(y-y2)/(x-x2),代入就可以得证

那么我们选定一些原料。这些原料能合成的合金一定在这些点所在的凸包上 证明略

于是我们就把问题转化成了这样:给定两个点集A和B,求A中最小的一个子集S。使B中全部的点在S的凸包内部

这个问题怎么处理呢?这里用到一个十分巧妙的方法

如图,枚举A点集两点i,j(i能够等于j)若B点集中的全部点都在向量i->j的左側或线段ij上(图中红色的点)而没有点在图中绿色的点所在位置。就连接一条i->j的单向边

即 若随意B点集中的点k满足(k->i)×(k->j)<0||(k->i)×(k->j)==0&&(k->i)·(k->j)<=0 则连接一条i->j的单向边

然后Floyd求最小环就可以

正确性自己YY吧 这样写应该是能够降低非常多讨论而且不会被卡掉的 顺便吐槽一句数据实在太弱……

  1. #include<cmath>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #define M 510
  7. #define INF 0x3f3f3f3f
  8. #define EPS 1e-7
  9. using namespace std;
  10. struct point{
  11. double x,y;
  12. point operator - (const point z)
  13. {
  14. point re;
  15. re.x=x-z.x;
  16. re.y=y-z.y;
  17. return re;
  18. }
  19. double operator * (const point z)
  20. {
  21. return x*z.y-y*z.x;
  22. }
  23. double operator ^ (const point z)//大家好我是萌萌哒的点积 乘号被叉积抢了主人仅仅能给我这个了~
  24. {
  25. return x*z.x+y*z.y;
  26. }
  27. }a[M],b[M];
  28. int m,n;
  29. int map[M][M],f[M][M];
  30. int ans=INF;
  31. void Floyd()
  32. {
  33. int i,j,k;
  34. memcpy(f,map,sizeof f);
  35. for(k=1;k<=m;k++)
  36. for(i=1;i<=m;i++)
  37. if(f[i][k]<INF)
  38. for(j=1;j<=m;j++)
  39. f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
  40. for(i=1;i<=m;i++)
  41. ans=min(ans,f[i][i]);
  42. }
  43. int main()
  44. {
  45. int i,j,k;
  46. memset(map,0x3f,sizeof map);
  47. cin>>m>>n;
  48. for(i=1;i<=m;i++)
  49. scanf("%lf%lf%*lf",&a[i].x,&a[i].y);
  50. for(i=1;i<=n;i++)
  51. scanf("%lf%lf%*lf",&b[i].x,&b[i].y);
  52. for(i=1;i<=m;i++)
  53. for(j=1;j<=m;j++)
  54. {
  55. for(k=1;k<=n;k++)
  56. {
  57. double cross=(a[i]-b[k])*(a[j]-b[k]);
  58. if( cross>EPS )
  59. break;
  60. if( fabs(cross)<EPS && (a[i]-b[k]^a[j]-b[k])>EPS )
  61. break;
  62. }
  63. if(k==n+1)
  64. map[i][j]=1;
  65. }
  66. Floyd();
  67. if(ans==INF)
  68. ans=-1;
  69. cout<<ans<<endl;
  70. }

BZOJ 1027 JSOI2007 合金 计算几何+Floyd的更多相关文章

  1. BZOJ 1027: [JSOI2007]合金 (计算几何+Floyd求最小环)

    题解就看这位仁兄的吧-不过代码还是别看他的了- 同样的方法-我200ms,他2000ms. 常数的幽怨- CODE #include <bits/stdc++.h> using names ...

  2. BZOJ 1027 [JSOI2007]合金 ——计算几何

    我们可以把每一种金属拆成一个二维向量,显然第三维可以计算出来,是无关的. 我们只需要考虑前两维的情况,显然可以构成点集所形成的凸包内. 然后我们枚举两两的情况,然后可以发现如果所有的点都在一侧是可以选 ...

  3. bzoj 1027 [JSOI2007]合金(计算几何+floyd最小环)

    1027: [JSOI2007]合金 Time Limit: 4 Sec  Memory Limit: 162 MBSubmit: 2970  Solved: 787[Submit][Status][ ...

  4. BZOJ 1027 [JSOI2007]合金

    1027: [JSOI2007]合金 Time Limit: 4 Sec  Memory Limit: 162 MBSubmit: 2605  Solved: 692[Submit][Status][ ...

  5. bzoj 1027: [JSOI2007]合金【凸包+Floyd】

    参考:https://www.cnblogs.com/zhuohan123/p/3237246.html 因为一c可以由1-a-b得出,所以删掉c,把a,b抽象成二维平面上的点.首先考虑一个客户需求能 ...

  6. [bzoj 1027][JSOI2007]合金(解析几何+最小环)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1027 分析: 首先因为一个合金的和为1,所以考虑2个材料合金能否合成一个需求合金的时候 ...

  7. 【BZOJ】1027: [JSOI2007]合金(凸包+floyd)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1027 题意:$n$种材料,$m$种需求.每种材料有三个属性,给出三个属性的含量(和为1),问能否通过 ...

  8. 1027: [JSOI2007]合金 - BZOJ

    Description 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的 ...

  9. 【BZOJ 1027】 (凸包+floyd求最小环)

    [题意] 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金 ...

随机推荐

  1. linux学习之高并发服务器篇(二)

    高并发服务器 1.线程池并发服务器 两种模型: 预先创建阻塞于accept多线程,使用互斥锁上锁保护accept(减少了每次创建线程的开销) 预先创建多线程,由主线程调用accept 线程池 3.多路 ...

  2. Launcher3实现壁纸居中

    Launcher3的wallpaper显示是动态的,与Launcher预置桌面数目有关,让壁纸居中,仅仅能确保第一次开机时壁纸居中,后面用户改动桌面数目后,就无法达到了.怎样要在默认桌面数目配置时居中 ...

  3. ZOJ 2588 Burning Bridges(无向连通图求割边)

    题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...

  4. Visual Code中的智能提示

    https://code.visualstudio.com/docs/editor/intellisense C# https://marketplace.visualstudio.com/items ...

  5. MVC:一个View显示多个Model(多个Model你可以使用ViewBag或ViewData , 或者:Model["myInfo"] as)

    MVC:一个View显示多个Model 多个Model你可以使用ViewBag或ViewData , 或者:Model["myInfo"] as. 比如: Tuple<str ...

  6. C++实现矩阵求逆

    最近实现一个算法要用到求逆等矩阵运算,在网上搜到一个别人写的矩阵类,试了一下效果不错,贴在这里,做个保存. matrix.h文件: #ifndef __MATRIX_H__ #define __MAT ...

  7. Linux 如何重新划分Swap交换分区

    SWAP分区是LINUX暂时存储数据的交换分区,它主要是把主内存上暂时不用得数据存起来,在需要的时候再调进内存内,且作为SWAP使用的分区不用指定“MoutPoint”(载入点)它至少要等于系统上实际 ...

  8. 再次学习 Iterator 迭代器 与 Generator 生成器

    Iterator : 返回的结果是:{value, done} function chef(foods){ let i = 0; return { next(){ let done = ( i> ...

  9. 紫书 习题 10-19 UVa 10868 (物理动能定理)

    这道题看起来很长,而实际上就是考物理 可以用动能定理来算出末速度. 同时注意要特判绳子比桥还长的情况. #include<cstdio> #include<cmath> #de ...

  10. 页面打开pdf格式文件的方法

    <embed width=500 height=300 fullscreen=yes src="1.pdf" />