zoukankan      html  css  js  c++  java
  • GYM

    题意:

      大矩形代表市场,大矩形当中有很多小矩形样式的伞。这些小矩形都贴着大矩形的左边或者右边且互不相交。小矩形以外的地方都是阳光。求经过大矩形时在阳光下的最短时间。

    题解:

      最短路的做法。起点和终点与每个矩形之间连边,每两个矩形之间也连边。

      矩形之间两边有三种情况:1.两个矩形在同一边(k值相等)或两个矩形的宽度和大于(不能大于等于)大矩形的宽度

                  2.两个矩形的长度区间不相交(a[i].h+a[i].d<a[j].d||a[j].h+a[j].d<a[i].d)

                  3.长度区间相交

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int t, n, vis[105];
    double L, U;
    double diss[105];
    struct rec {
        double h, w, d;
        int k;
    }r[105];
    struct node {
        int to;
        double val;
        node(int a, double b) {
            to = a; val = b;
        }
    };
    vector<node> g[105];
    double distance(double x1, double y1, double x2, double y2) {
        return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
    }
    void add_edge(int u, int v, double val) {
        g[u].push_back(node(v, val));
        g[v].push_back(node(u, val));
    }
    void unite(int u, int v) {
        double dis;
        if(r[u].k==r[v].k || r[u].w+r[v].w > U) 
        dis = max(r[u].d-r[v].d-r[v].h, r[v].d-r[u].d-r[u].h);
        else {
            if(r[u].d > r[v].d+r[v].h) dis = distance(r[u].w, r[u].d, U-r[v].w, r[v].d+r[v].h);
            else if(r[v].d > r[u].d+r[u].h) dis = distance(r[v].w, r[v].d, U-r[u].w, r[u].d+r[u].h);
            else dis = U-r[u].w-r[v].w;
        }
        add_edge(u, v, dis);
    }
    void spfa(int s) {
        queue<int> q;
        q.push(s);
        memset(vis, 0, sizeof(vis));
        vis[s] = 1;
        while(!q.empty()) {
            int v = q.front();
            q.pop();
            vis[v] = 0;
            int len = g[v].size();
            for(int i = 0; i < len; i++) {
                if(g[v][i].val+diss[v] < diss[g[v][i].to]) {
                    diss[g[v][i].to] = g[v][i].val+diss[v];
                    if(!vis[g[v][i].to]) {
                        q.push(g[v][i].to);
                        vis[g[v][i].to] = 1;
                    }
                }
            }
        }
    }
    int main() {
        freopen("street.in","r",stdin);
        scanf("%d", &t);
        while(t--) {
            scanf("%d%lf%lf", &n, &L, &U);
            for(int i = 0; i <= n+1; i++) {
                g[i].clear();
                if(i) diss[i] = 1e15;
            }
            for(int i = 1; i <= n; i++) scanf("%lf%lf%lf%d", &r[i].h, &r[i].w, &r[i].d, &r[i].k);
            for(int i = 1; i <= n; i++) {
                add_edge(0, i, r[i].d);
                add_edge(n+1, i, L-r[i].d-r[i].h);
            }
            for(int i = 1; i < n; i++)
            for(int j = i+1; j <= n; j++) 
                unite(i, j);
            spfa(0);
            printf("%.6lf
    ", diss[n+1]);
        }
    }
    View Code
  • 相关阅读:
    通俗易懂----欧几里得算法
    安卓贴图源码--->记录旋转后位置..类似in/百度魔图
    wait、notify、sleep、interrupt对比分析
    安卓内存泄漏及检测内存泄漏
    美团多渠道打包
    高版本api在低版本中的兼容
    常用工具
    双守护进程(不死service)-5.0系统以下
    安卓log4k问题解决
    10、面向对象以及winform的简单运用(isMdicontainer的设置、timer控件进行倒计时的制作)
  • 原文地址:https://www.cnblogs.com/Pneuis/p/8900703.html
Copyright © 2011-2022 走看看