zoukankan      html  css  js  c++  java
  • bzoj1027: [JSOI2007]合金

    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。

    c=1-a-b,可以忽略c。

    选出的原材料所在的点的凸包必须包含(含边界)所有所需合金所在的点,因此可以特判答案为1,2的情况,否则答案>2,对每对原材料,若所有所需合金所在的点在其左侧(含边界),则连有向边,图中的最小环即为答案。

    #include<cstdio>
    #include<algorithm>
    const double eps=1e-10;
    const int inf=0x1f1f1f1f;
    double _;
    int m,n;
    struct pos{
        double x,y;
        bool operator==(pos w)const{return x==w.x&&y==w.y;}
        bool operator<(pos w)const{return x!=w.x?x<w.x:y<w.y;}
        double operator*(pos w)const{return x*w.y-y*w.x;}
        double mul(pos w)const{return x*w.x+y*w.y;}
        pos operator-(pos w)const{return (pos){x-w.x,y-w.y};}
    }p1[507],p2[507];
    int f[507][507];
    void mins(int&a,int b){if(a>b)a=b;}
    int main(){
        scanf("%d%d",&m,&n);
        for(int i=0;i<m;++i)scanf("%lf%lf%lf",&p1[i].x,&p1[i].y,&_);
        for(int i=0;i<n;++i)scanf("%lf%lf%lf",&p2[i].x,&p2[i].y,&_);
        std::sort(p1,p1+m);
        m=std::unique(p1,p1+m)-p1;
        std::sort(p2,p2+n);
        n=std::unique(p2,p2+n)-p2;
        if(n==1){
            for(int i=0;i<m;++i)if(p1[i]==p2[0])return puts("1"),0;
        }
        for(int i=0;i<m;++i){
            f[i][i]=inf;
            for(int j=0;j<i;++j){
                bool dl=1,dr=1;
                for(int k=0;k<n&&(dl|dr);++k){
                    double v=(p2[k]-p1[i])*(p1[j]-p1[i]);
                    if(v<-eps)dl=0;
                    if(v>eps)dr=0;
                }
                f[i][j]=dl?1:inf;
                f[j][i]=dr?1:inf;
                if(dl&&dr){
                    for(int k=0;k<n;++k){
                        if((p2[k]-p1[i]).mul(p2[k]-p1[j])>eps)goto o;
                    }
                    return puts("2"),0;
                    o:;
                }
            }
        }
        for(int k=0;k<m;++k)
        for(int i=0;i<m;++i)
        for(int j=0;j<m;++j)mins(f[i][j],f[i][k]+f[k][j]);
        int ans=inf;
        for(int i=0;i<m;++i)mins(ans,f[i][i]);
        if(ans<3||ans==inf)ans=-1;
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    jmeter脚本在非GUI模式下运行_增加请求和返回_记录
    scp从一台服务器复制文件到本台服务器
    crontab定时任务配置
    jmeter非GUI模式_单点运行
    jmeter非GUI模式_分布式运行
    Dede 查询附加表
    Dede 列表文章 自增
    dede密码忘记 的修改方法
    CSS 字体描边
    教你如何去掉点击链接时的虚线
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6179140.html
Copyright © 2011-2022 走看看