[BZOJ 1027]合金

来源:互联网 发布:淘宝书店店铺介绍 编辑:程序博客网 时间:2024/04/28 02:58

求一个包围所有点且选中点的个数最小的集合


那么就是要求一个凸包,且包围所有点,凸包上的点最少


竟然是Floyd最小环


注意共点和共线


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define maxn 510using namespace std; int n, m;//--------------------------------------------------------------//const double eps = 1e-10;int Filter(double x){return x>eps?1:(x<-eps?-1:0);} double mytest;struct Point{    double x, y;    Point(double x = 0, double y = 0):x(x), y(y){}    void read(){scanf("%lf%lf%lf", &x, &y, &mytest);}    void print(){printf("%lf %lf\n", x, y);}    bool operator!=(const Point &k)const{        return Filter(x - k.x) || Filter(y - k.y);    }}a[maxn], b[maxn];Point operator-(const Point& a,const Point& b){    return Point(a.x - b.x, a.y - b.y);}double Cross(const Point& a,const Point& b){    return a.x * b.y - a.y * b.x;}double Dot(const Point& a,const Point& b){    return a.x * b.x + a.y * b.y;}double length(const Point& a){    return sqrt(a.x * a.x + a.y * a.y);}//--------------------------------------------------------------//int dis[maxn][maxn]; bool Special_Judge(){    for(int j = 2; j <= n; j ++)        if(b[j] != b[j - 1])            return false;     for(int i = 1; i <= m; i ++){        int cnt = 0;        for(int j = 1; j <= n; j ++){            if(a[i] != b[j])break;            cnt ++;        }        if(cnt == n){            puts("1");            return true;        }    }    return false;} bool Special_Judge2(){    Point u = b[1] - b[2];    for(int i = 3; i <= n; i ++)        if(Filter(Cross(u, b[i] - b[1])))            return false;    for(int i = 1; i <= m; i ++){        for(int j = i + 1; j <= m; j ++){            int flag = true;            if(Filter(Cross(a[i] - b[1], a[j] - b[1])))                continue;            for(int k = 1; k <= n; k ++){                if(Filter(Dot(a[i] - b[k], a[j] - b[k])) > 0){                    flag = false;                    break;                }            }            if(flag){                puts("2");                return true;            }        }    }    if(m == 2){        puts("-1");        return true;    }    return false;}//--------------------------------------------------------------//int tmp[maxn];bool check(int u, int v){    for(int i = 1; i <= n; i ++)        if(Filter(Cross(a[v] - a[u], b[i] - a[u])) < 0)            return false;    return true;} const int inf = 0x7fffffff;int Floyd(){    int ans = inf;    for(int k = 1; k <= m; k ++)        for(int i = 1; i <= m; i ++)            if(dis[i][k] < inf)                for(int j = 1; j <= m; j ++)                    dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);    for(int i = 1; i <= m; i ++)        ans = min(ans, dis[i][i]);    if(ans > m || ans <= 2)        return -1;    return ans;} int main(){     memset(dis, 127 / 3, sizeof dis);    scanf("%d%d", &m, &n);     for(int i = 1; i <= m; i ++)        a[i].read();    for(int i = 1; i <= n; i ++)        b[i].read();    if(n == 0){        puts("0");        return 0;    }    if(Special_Judge())        return 0;    if(Special_Judge2())        return 0;    for(int i = 1; i <= m; i ++)        for(int j = 1; j <= m; j ++)            if(i != j && check(i, j))                dis[i][j] = 1;     printf("%d\n", Floyd());     return 0;}


0 0
原创粉丝点击