zoukankan      html  css  js  c++  java
  • 【BZOJ 1027】 (凸包+floyd求最小环)

    【题意】

      某公司加工一种由铁、铝、锡组成的合金。他们的工作很简单。首先进口一些铁铝锡合金原材料,不同种类的
    原材料中铁铝锡的比重不同。然后,将每种原材料取出一定量,经过融解、混合,得到新的合金。新的合金的铁铝
    锡比重为用户所需要的比重。 现在,用户给出了n种他们需要的合金,以及每种合金中铁铝锡的比重。公司希望能
    够订购最少种类的原材料,并且使用这些原材料可以加工出用户需要的所有种类的合金。

    【分析】

      只要考虑前两个物质的比例,因为加起来等于1。

      如果你看过zoj3154,就会知道这题的模型,用二元组表示合金(x1,y1)(x2,y2),他们能混合成的合金就是线段(x1,y1)->(x2,y2),

      那么一堆点组成的合金就是那些点组成的凸包面积。

      然后看了po姐的下一步转化,就是若点i->j的一侧包含了所有B点集,那么i->j连一条边,然后floyd求最小环即可。

      有一个地方我一开始错了:若B中有一个点在i->j上,要判断是不是线段上的,若只是直线上,也是不能组成的。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Maxn 510
     8 #define INF 0x7fffffff
     9 
    10 int m,n;
    11 
    12 int mymin(int x,int y) {return x<y?x:y;}
    13 
    14 const double eps=0.0001;
    15 
    16 struct node
    17 {
    18     double x,y;
    19 };
    20 node t[Maxn*2];
    21 
    22 node operator - (node x,node y)
    23 {
    24     node P;
    25     P.x=x.x-y.x;P.y=x.y-y.y;
    26     return P;
    27     // return node{x.x-y.x,x.y-y.y};
    28 }
    29 
    30 double myabs(double x) {return x>0?x:-x;}
    31 
    32 bool operator != (node x,node y) {return myabs(x.x-y.x)>eps||myabs(x.y-y.y)>eps;}
    33 
    34 double Cross(node x,node y)
    35 {
    36     return x.x*y.y-x.y*y.x;
    37 }
    38 
    39 double Dot(node x,node y)
    40 {
    41     return x.x*y.x+x.y*y.y;
    42 }
    43 
    44 int dis[Maxn][Maxn];
    45 
    46 void floyd()
    47 {
    48     for(int k=1;k<=m;k++)
    49      for(int i=1;i<=m;i++)
    50       for(int j=1;j<=m;j++)
    51          dis[i][j]=mymin(dis[i][j],dis[i][k]+dis[k][j]);
    52 }
    53 
    54 int main()
    55 {
    56     scanf("%d%d",&m,&n);
    57     for(int i=1;i<=m+n;i++)
    58     {
    59         double c;
    60         scanf("%lf%lf%lf",&t[i].x,&t[i].y,&c);
    61     }
    62     memset(dis,63,sizeof(dis));
    63     for(int i=1;i<=m;i++)
    64      for(int j=1;j<=m;j++) //if(i!=j&&t[i]!=t[j])
    65      {
    66          bool ok=1;
    67          for(int k=m+1;k<=n+m;k++)
    68          {
    69              if(Cross(t[j]-t[i],t[k]-t[i])>eps) {ok=0;break;}
    70              if(myabs(Cross(t[j]-t[i],t[k]-t[i]))<=eps&&Dot(t[i]-t[k],t[j]-t[k])>eps) {ok=0;break;}
    71          }
    72          if(ok) dis[i][j]=1;
    73          // if(ok) {dis[i][j]=1;printf("%d->%d
    ",i,j);}
    74      }
    75     floyd();
    76     int ans=INF;
    77     for(int i=1;i<=m;i++) ans=mymin(ans,dis[i][i]);
    78     if(ans>m) ans=-1;
    79     printf("%d
    ",ans);
    80     return 0;
    81 }
    View Code

    2017-02-20 22:09:40

  • 相关阅读:
    ST3 插件和技巧
    博客园中 代码使用 sublime-text 的主题
    JavaScript中的 prototype 和 constructor
    JavaScript 代码小片段
    JavaScript 静态方法和实例方法
    JavaScript 闭包的例子
    关于linux 交叉编译器的安装
    scrapy 实现mysql 数据保存
    django 实现 内网访问 和 用花生壳进行内网穿透
    django 中从外界借助多个网站时 static 的存放和整理
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6421791.html
Copyright © 2011-2022 走看看