• bzoj1027: [JSOI2007]合金


    凸包,floyd求最小环。

    首先第三个变量是可以由变量1,2得到的,所以可以省去。

    然后如果产品在由原材料构成的凸包里,它就是可以被合成的。

    所以问题就是要求包含所有产品的最小的凸包。

    所以所有取到的边都在确定的一侧,所以先判断出哪些边可以取,跑floyd最小环就可以了。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define eps 1e-10
    using namespace std;
    const int maxn = 500+10;
    const int inf = 0x3f3f3f3f;
    
    struct Point {
        double x,y;
        Point(double _x=0,double _y=0):x(_x),y(_y) {}
    }mat[maxn],req[maxn];
    
    struct Vector {
        double x,y;
        double operator* (Vector b) {return x*b.y-y*b.x;}    
        Vector(double _x=0,double _y=0):x(_x),y(_y) {}
        Vector(Point a,Point b):x(b.x-a.x),y(b.y-a.y) {}
    };
    
    double t;
    
    int sgn(double x) {
        if(abs(x) < eps) return 0;
        else if(x>0) return 1;
        else return -1;    
    }
    
    bool check_line(Point ls,Point le,Point p) {
        return (ls.x>p.x && le.x>p.x) ||
               (ls.x<p.x && le.x<p.x) ||
               (ls.y>p.y && le.y>p.y) ||
               (ls.y<p.y && le.y<p.y) ;
    }    
    
    int g[maxn][maxn];
    int n,m;
    
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&mat[i].x,&mat[i].y,&t);
        for(int i=1;i<=m;i++) scanf("%lf%lf%lf",&req[i].x,&req[i].y,&t);
        for(int i=1;i<=n;i++) {
            bool flag=true;
            for(int j=1;j<=m;j++) 
                if(sgn(mat[i].x-req[j].x)||sgn(mat[i].y-req[j].y)) {flag=false; break;}
            if(flag) {printf("1
    ",i); return 0;}
        }
        
        memset(g,0x3f,sizeof(g));
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) if(i!=j){
            if(!sgn(mat[i].x-mat[j].x) && !sgn(mat[i].y-mat[i].y)) continue;
            
            bool able=true;
            for(int k=1;k<=m;k++) if(sgn(Vector(mat[i],mat[j])*Vector(mat[i],req[k]))==-1) {
                able=false;
                break;
            }
            if(able) {
                for(int k=1;k<=m;k++) 
                    if(sgn(Vector(mat[i],mat[j])*Vector(mat[i],req[k]))==0&&check_line(mat[i],mat[j],req[k])) {
                        able=false;
                        break;
                    }
            }
            if(able) g[i][j]=1;
        }
        
        int res=inf;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        for(int k=1;k<=n;k++)
            g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
        
        for(int i=1;i<=n;i++) 
        for(int j=1;j<=n;j++) {
            if(i!=j) res=min(res,g[i][j]+g[j][i]);
            else res=min(res,g[i][i]);
        }
        printf("%d
    ",res>n?-1:res); 
        return 0;
    }
  • 相关阅读:
    echarts模拟highcharts实现折线图的虚实转换
    Chrome开发者工具详解 (5):Application、Security、Audits面板
    Chrome 开发者工具详解(4):Profiles 面板
    Chrome开发者工具详解(3):Timeline面板
    Chrome 开发者工具详解(2):Network 面板
    Chrome开发者工具详解(1):Elements、Console、Sources面板
    移动前端开发之 viewport 的深入理解
    响应式图片
    JS中的函数节流
    总结oninput、onchange与onpropertychange事件的用法和区别 书写搜索的神奇代码
  • 原文地址:https://www.cnblogs.com/invoid/p/5584972.html
Copyright © 2020-2023  润新知