zoukankan      html  css  js  c++  java
  • bzoj1390 [Ceoi2008]Fence

    [Ceoi2008]Fence

    Time Limit: 10 Sec Memory Limit: 64 MB

    Description

    在一个大小为1000*1000的区域中,有n个固定点,m棵tree 。 现在你要建一个围栏来保护tree,建它的费用为你选用的固定点的个数 20和 你没有圈进围栏的tree111. 现在希望这个值越小越好. 3<=N<=100. 1<=M<=100

    Input

    第一行给出n,m 下面开始n行,给出固定的坐标 下面开始m行,给出tree的坐标

    Output

    输出最小费用

    Sample Input

    4 3

    800 300

    200 200

    200 700

    600 700

    400 300

    600 500

    800 900

    Sample Output

    171

    HINT




    这是道真好的凸包模板题啊。。。 显然3 * 20 < 111 所以直接能包就爆呗。。。 感觉做出这道题就凸包入门了。 首先你要会求凸包。 然后你还有会判断点是否在凸包内。 最后还要会不停的缩小凸包,floyd找最小环。 良心入门题啊(以后应该就是**题了吧qwq)
    ```c++

    include<bits/stdc++.h>

    define N 105

    define eps 1e-8

    using namespace std;
    struct point{
    double x, y;
    inline point operator + (const point &A)const{return (point){x + A.x, y + A.y};}
    inline point operator - (const point &A)const{return (point){x - A.x, y - A.y};}
    inline point operator * (const point &A)const{return (point){x * A.x, y * A.y};}
    inline bool operator < (const point &A)const{return x < A.x;}
    }gu[N], tree[N], s[N];
    int n, m, tot, ans, psize, dis[N][N];
    vector p;

    inline double cross(point A, point B){return A.x * B.y - A.y * B.x;}

    inline bool onleft(point A, point B, point P){return cross(B - A, P - A) >= -eps;}

    inline bool onright(point A, point B, point P){return cross(B - A, P - A) <= eps;}

    inline void putit(){
    scanf("%d%d", &n, &m); ans += 111 * m;
    for(int i = 1; i <= n; ++i) scanf("%lf%lf", &gu[i].x, &gu[i].y);
    for(int i = 1; i <= m; ++i) scanf("%lf%lf", &tree[i].x, &tree[i].y);
    }

    inline void tb(){
    sort(gu + 1, gu + n + 1);
    s[++tot] = gu[1];
    for(int i = 2; i <= n; ++i){
    while(tot > 1 && !onleft(s[tot - 1], s[tot], gu[i])) tot--;
    s[++tot] = gu[i];
    }
    for(int i = n - 1; i >= 1; --i){
    while(tot > 1 && !onleft(s[tot - 1], s[tot], gu[i])) tot--;
    s[++tot] = gu[i];
    }
    tot--;
    }

    inline bool check(point A){
    if(A.x < gu[1].x || A.x > gu[n].x) return false;
    int L = 2, R = tot + 1;
    while(L < R){
    int mid = (L + R) >> 1;
    if(onright(s[1], s[mid], A)) R = mid;
    else L = mid + 1;
    }
    if(L == 2 || L == tot + 1) return false;
    return onright(s[L], s[L - 1], A);
    }

    inline void prepare(){
    s[tot + 1] = (point){s[1].x, 10000};
    for(int i = 1; i <= m; ++i)
    if(check(tree[i])){
    p.push_back(tree[i]); ans -= 111;
    }
    psize = p.size();
    }

    inline bool search(point A, point B){
    for(int i = psize - 1; i >= 0; --i)
    if(!onleft(A, B, p[i])) return false;
    return true;
    }

    inline void workk(){
    if(!psize){printf("%d", m * 111); return;}
    memset(dis, 0x3f, sizeof(dis));
    for(int i = 1; i <= n; ++i)
    for(int j = i + 1; j <= n; ++j){
    if(search(gu[i], gu[j])) dis[i][j] = 1;
    if(search(gu[j], gu[i])) dis[j][i] = 1;
    }
    for(int k = 1; k <= n; ++k)
    for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= n; ++j)
    dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
    int Ans = 1e9;
    for(int i = 1; i <= n; ++i) Ans = min(Ans, dis[i][i]);
    ans += Ans * 20;
    cout << ans;
    }

    int main()
    {
    putit();
    tb();
    prepare();
    workk();
    return 0;
    }

  • 相关阅读:
    网页表单项Input的高级限制级用法
    程序员从初级到中级10个秘诀
    AspNet2.0页面生命周期(转载)
    WebService大讲堂之Axis2(4):二进制文件传输
    WebService大讲堂之Axis2(9):编写Axis2模块(Module)
    WebService大讲堂之Axis2(7):将Spring的装配JavaBean发布成WebService
    WebService大讲堂之Axis2(10):使用soapmonitor模块监视soap请求与响应消息
    WebService大讲堂之Axis2(5):会话(Session)管理
    lucence(补)
    WebService大讲堂之Axis2(6):跨服务会话(Session)管理
  • 原文地址:https://www.cnblogs.com/LLppdd/p/9950552.html
Copyright © 2011-2022 走看看