zoukankan      html  css  js  c++  java
  • HDU 4606 Occupy Cities (计算几何+最短路+最小路径覆盖)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

    题目:给出n个城市需要去占领,有m条线段是障碍物,有p个士兵可以用。占领城市有个先后顺序,每个士兵有个背包,占领城市之后,仅能补给一次背包。问背包容量最少是多少,可以用这P个士兵完成任务,起点任意 。

    http://acm.hdu.edu.cn/showproblem.php?pid=4606

    首先:枚举所有顶点,求一下距离,判断是否与线段相交。然后 floyd预处理最短路

    之后是二分答案,判断是否可达

    根据占领的先后顺序建边,根据二分的值判断不需要补给是否能够到达。

    之后便是判断最小路径覆盖数是否小于等于P。

    #include <iostream>
    #include <queue>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int N = 505;
    const int M = 3000000;
    const int INF = 100000;
    const double eps = 1e-7;
    inline int dcmp(double d){
        return d < -eps? -1 : d > eps;
    }
    inline double sqr(double d){
        return d * d;
    }
    struct Point {
        double x, y;
        Point (){}
        Point (double _x,double _y):x(_x),y(_y){}
        inline bool operator == (const Point &p)const {
            return (dcmp(x - p.x) == 0 && dcmp(y - p.y) == 0);
        }
        inline Point operator - (const Point &p)const {
            return Point(x - p.x,y - p.y);
        }
        inline double operator * (const Point &p)const {
            return x * p.y - y * p.x;
        }
        inline double operator / (const Point &p)const {
            return x * p.x + y * p.y;
        }
        inline double Distance(Point p){
            return sqrt(sqr(p.x - x) + sqr(p.y - y));
        }
        void input(){
            scanf ("%lf %lf", &x, &y);
        }
    }p[N];
    struct Line{
        Point a,b;
        void input(){
            a.input();
            b.input();
        }
        Line(){}
        Line(Point _a,Point _b):a(_a),b(_b){}
        inline bool operator == (const Line &l) const{
            return (a == l.a && b == l.b) || (a == l.b && b == l.a);
        }
        inline double operator * (const Point &p)const {
            return (b - a) * (p - a);
        }
        inline double operator / (const Point &p)const {
            return (p - a) / (p - b);
        }
        inline int SegCrossSeg(const Line &v){
            int d1 = dcmp((*this) * v.a);
            int d2 = dcmp((*this) * v.b);
            int d3 = dcmp(v * a);
            int d4 = dcmp(v * b);
            if((d1 ^ d2) == -2 && (d3 ^ d4) == -2) return 2;
            return ((d1 == 0 && dcmp((*this) / v.a) <= 0)
                ||(d2 == 0 && dcmp((*this) / v.b) <= 0)
                ||(d3 == 0 && dcmp(v / a) <= 0)
                ||(d4 == 0 && dcmp(v / b) <= 0) );
        }
    }l[N];
    int n , m , K , seq[N];
    int match[N], vis[N];
    double dist[N][N];
    int tot , start[N];
    struct Edge {
        int v, next;
    }e[N * N];
    void _add (int u , int v) {
        e[tot].v = v;
        e[tot].next = start[u];
        start[u] = tot ++;
    }
    bool dfs (int u) {
        for (int i = start[u] ; i != -1 ; i = e[i].next) {
            int v = e[i].v;
            if (! vis[v]) {
                vis[v] = 1;
                if(match[v] == -1 || dfs(match[v])) {
                    match[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    int hungry () {
        int ans = 0;
        memset (match , -1, sizeof(match)) ;
        for (int i = 1 ; i <= n ; i ++) {
            memset (vis , 0 , sizeof(vis));
            if (dfs(i)) ans ++;
        }
        return ans;
    }
    bool check (double mid) {
        tot = 0 ;
        memset (start , -1 , sizeof(start));
        for (int i =1 ; i <= n ; i ++) {
            for (int j = i + 1 ; j <= n ; j ++) {
                if(dist[seq[i]][seq[j]] <= mid) 
                    _add (seq[i] , seq[j] + n);
            }
        }
        return n - hungry() <= K;
    }
    double solve(){
        double l = 0 , r = INF;
        double ans = -1;
        int cnt = 50;
        while(cnt --){
            double mid = (l + r) * 0.5;
            if(check(mid)){
                ans = mid;
                r = mid;
            }
            else l = mid;
        }
        return ans;
    }
    int main(){
        int t;
        scanf ("%d", &t);
        while (t --){
            scanf ("%d%d%d", &n, &m, &K);
            for (int i = 1 ; i <= n ; i ++){
                p[i].input();
            }
            for (int i = 1 ; i <= m ; i ++){
                l[i].input();
                p[n + (i - 1) * 2 + 1] = l[i].a;
                p[n + i * 2] = l[i].b;
            }
            for (int i = 1 ; i <= n + m * 2 ; i ++){
                for (int j = 1 ; j <= n + m * 2 ; j ++){
                    if(i == j) dist[i][j] = 0.0;
                    else {
                        bool flag = false;
                        for (int k = 1 ; k <= m ; k ++){
                            if(l[k] == Line(p[i] , p[j])) continue;
                            if (l[k].SegCrossSeg(Line(p[i] , p[j])) == 2) {
                                flag = true;
                                break ; 
                            }
                        }
                        if(flag) dist[i][j] = 1e9;
                        else dist[i][j] = p[i].Distance(p[j]);
                    }
                }
            }
            for(int i = 1;i <= n;i ++){
                scanf("%d",&seq[i]);
            }
            for (int k = 1 ; k <= n + m * 2 ; k ++) {
                for (int i = 1 ; i <= n + m * 2 ; i ++) {
                    for (int j = 1 ; j <= n + m * 2 ;j ++ ){
                        dist[i][j] = fmin(dist[i][j] , dist[i][k] + dist[k][j]);
                    }
                }
            }
            double ans = solve();
            printf("%.2f
    ",ans);
        }
        return 0;
    }


  • 相关阅读:
    dubbo源码阅读-服务订阅(八)之本地订阅(injvm)
    dubbo源码阅读-服务订阅(八)之主流程
    dubbo源码阅读-服务暴露(七)之远程暴露(dubbo)
    dubbo源码阅读-配置(二)之API配置
    dubbo源码阅读-容器启动(六)
    LIRe 源代码分析 6:检索(ImageSearcher)[以颜色布局为例]
    LIRe 源代码分析 5:提取特征向量[以颜色布局为例]
    LIRe 源代码分析 4:建立索引(DocumentBuilder)[以颜色布局为例]
    智能电视大战背后的秘密
    二线视频网站突围战
  • 原文地址:https://www.cnblogs.com/aukle/p/3215140.html
Copyright © 2011-2022 走看看