uva 1001 建图+最短路

题意:

在一个三维的空间内求从起点到终点的最短时间花费。

其中n个洞,在洞内通过的时间花费是0,在洞外的时间花费是每单位10sec

思路:

水题

建立起点到每个洞的边,建立终点到每个洞的边,建立起点到终点的边 ,边权是到达所需的时间花费。求一次最短路即可。

code:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

const int maxn = 105;

int n;
struct ball{
    double x, y, z, r;
    ball(){}
    ball(double x_, double y_, double z_, double r_){
        x = x_;
        y = y_;
        z = z_;
    }
}bb[maxn];
double sx,sy,sz,ex,ey,ez;

const int INF = 0x3f3f3f3f;
const int MAXNODE = 110;
struct Edge{
    int u, v;
    double dist;
    Edge() {}
    Edge(int u, int v, double dist) {
        this->u = u;
        this->v = v;
        this->dist = dist;
    }
};
struct HeapNode {
    int u;
    double d;
    HeapNode() {}
    HeapNode(double d, int u) {
        this->d = d;
        this->u = u;
    }
    bool operator < (const HeapNode& c) const {
        return d > c.d;
    }
};
struct Dijkstra {
    int n, m;
    vector<Edge> edges;
    vector<int> g[MAXNODE];
    bool done[MAXNODE];
    double d[MAXNODE];
    int p[MAXNODE];

    void init(int tot) {
        n = tot;
        for (int i = 0; i < n; i++)
            g[i].clear();
        edges.clear();
    }

    void add_Edge(int u, int v, double dist) {
        edges.push_back(Edge(u, v, dist));
        m = edges.size();
        g[u].push_back(m - 1);
    }

    void dijkstra(int s) {
        priority_queue<HeapNode> Q;
        for (int i = 0; i < n; i++) d[i] = (double)INF;
        d[s] = 0;
        memset(done, false, sizeof(done));
        Q.push(HeapNode(0, s));
        while (!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            for (int i = 0; i < g[u].size(); i++) {
                Edge& e = edges[g[u][i]];
                if (d[e.v] > d[u] + e.dist) {
                    d[e.v] = d[u] + e.dist;
                    p[e.v] = g[u][i];
                    Q.push(HeapNode(d[e.v], e.v));
                }
            }
        }
    }
}gao;

double dist(ball b1, ball b2){
    double tmp = (b1.x - b2.x)*(b1.x - b2.x) + (b1.y - b2.y) * (b1.y - b2.y) + (b1.z - b2.z) * (b1.z - b2.z);
    return sqrt(tmp);
}
void init(){
    double x,y,z,r;
    for(int i = 0; i < n; i++){
        scanf("%lf%lf%lf%lf",&x,&y,&z,&r);
        bb[i].x = x;
        bb[i].y = y;
        bb[i].z = z;
        bb[i].r = r;
    }
    scanf("%lf%lf%lf",&sx,&sy,&sz);
    scanf("%lf%lf%lf",&ex,&ey,&ez);
    gao.init(n+2);
}
void deal(){
    ball b1(sx,sy,sz,0);
    for(int i = 0; i < n; i++){
        double w = dist(b1, bb[i]);
        w = w - bb[i].r;
        if(w < 0) w = 0;
        gao.add_Edge(i, n, w*10);
        gao.add_Edge(n, i, w*10);
    }
    ball b2(ex,ey,ez,0);
    for(int i = 0; i < n; i++){
        double w = dist(b2, bb[i]);
        w = w - bb[i].r;
        if(w < 0) w = 0;
        gao.add_Edge(i, n+1, w*10);
        gao.add_Edge(n+1, i, w*10);
    }

    for(int i = 0; i < n; i++){
        for(int j = i+1; j < n; j++){
            double w = dist(bb[i], bb[j]);
            w = w - bb[i].r - bb[j].r;
            if(w < 0) w = 0;
            gao.add_Edge(i, j, w*10);
            gao.add_Edge(j, i, w*10);
        }
    }

    double w = dist(b1, b2);
    gao.add_Edge(n, n+1, w*10);
    gao.add_Edge(n+1, n, w*10);
}
void solve(){
    gao.dijkstra(n);
    printf("%d sec\n",(int)(gao.d[n+1]+0.5));
}
int main(){
    int cas = 0;
    while(scanf("%d",&n) != EOF){
        if(n == -1) break;
        init();
        deal();
        printf("Cheese %d: Travel time = ",++cas);
        solve();
    }
    return 0;
}

注意最后的结果是四舍五入后的整形,这个地方wa了一发T_T

时间: 2024-10-25 20:05:38

uva 1001 建图+最短路的相关文章

Codeforces 787D. Legacy 线段树优化建图+最短路

output standard output Rick and his co-workers have made a new radioactive formula and a lot of bad guys are after them. So Rick wants to give his legacy to Morty before bad guys catch them. There are n planets in their universe numbered from 1 to n.

Hdu 5521 Meeting(建图+最短路)

题目地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5521 思路:边数太多,不能直接建图.对于每个集合,设置一个虚拟点,对于每个集合中的点u:连一条u->S权值为0的边(点在集合中,花费为0):连一条S->u权值为w的边(从集合中一点到另一点花费w).分别计算从点1到i和从点n到i的最短路,枚举i,则ans=min( ans,max ( dist[0][i],dist[1][i] ) ). #include<queue> #i

uva10067 Playing with Wheels 【建图+最短路】

题目:uva10067 Playing with Wheels 题意:给出一个机器,有四个循环的轮子,见图,然后给出一个初始数和目标数,然后期间不能出现的数字,每一分钟可以拨动一个数,问你最短需要的时间. 分析:这个题目可以转化为求图的最短路. 因为有对于一个当前状态,有8种可以转化为的状态,那么我们可以把每一种状态转化为一个点,然后状态之间连长度 1 的边,然后求一次初始状态到目标状态的最短路. 开始的时候我们每一组数据建图一次,下来0.9s,然后优化了一下,就是在每次建图不能到达的边删除之后

【建图+最短路】Bzoj1001 狼抓兔子

Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是

poj2502题解(建图+最短路)

题意 给起点和终点的坐标,然后给出多条地铁每一站的坐标,每站地铁只能到相邻的地铁站,地铁的速度是40km/h,人行走的速度是10km/h,求起点到终点的最小时间(给出的坐标单位是m,最后求的时间单位是分钟) 解题思路 这题关键点在与建图,把图建好后跑dijkstra就很简单了,之前一直wa是想复杂了,以为要考虑起点和终点在地铁站的情况和不同线路的地铁站相交的情况,后来想不需要这么麻烦,同一条线路相邻的40,不同的10就可以了,相交的话,以10km/h走时间花费是0. AC代码 #include<

CF-787D-线段树建图+最短路

http://codeforces.com/problemset/problem/787/D 题目大意是给出一个有向图,有N个节点,初始节点在S,询问S到所有点最短路.边的读入方式有三种, 1 u v w  表示 u->v有一条边权为w的边, 2 v l r w ,表示v->[l,r]内的任意一个点支付w即可, 3 v l r w 表示从[l,r]内任意一个点到v支付w即可.直接构图的话可能会出现完全图,被卡死. 一种巧妙的构图方式是,由这些个区间联想到线段树(然而我并没有想到),我们不妨对2

CF786B Legacy(线段树优化建图+最短路)

在qbxt某营集体做的 题解里以及外地OIer基本上都写两颗线段树的 而我们六安的OIer神TM思维一致--只用一颗线段树,类似于一维分层图的思想,第二层上与第一层相对应的结点的编号是第一层结点编号+NUM,而且貌似比分颗的思维正常一点,因为满足lson=k<<1,rson=k<<1|1,和一般的线段树相似度高. 至于为什么要分颗或分层,容易想明白树边(辅助边)必须是双向的(因为要用祖先结点的出入信息),但如果不分颗或分层的话求出来最短路不很明显是0了吗QwQ 所以分层的话父向子应

FJNU 1176 汪老司机(DP or 建图+最短路)

1196: 汪老司机 Time Limit: 1000 MS         Memory Limit: 257792 KB 64-bit interger IO format: %lld        Java class name: Main Prev Submit  Discuss Next 汪老司机是实验室出了名的老司机,早在大一就拿到了驾照,每年的暑假他都会带家人开车出游,今年的暑假也不例外,汪老司机今年准备带家人去平潭游玩,汪老司机的家离平潭有两条路,每条路都存在n个路段,两条路的n

建图最短路同余(luogu2662 vijos1054 xjoi2157)

描述 John计划为他的牛场建一个围栏,以限制奶牛们的活动.他有N种可以建造围栏的木料,长度分别是l1,l2…lN,每种长度的木料无限.修建时,他将把所有选中的木料拼接在一起,因此围栏的长度就是他使用的木料长度之和.但是聪明的John很快发现很多长度都是不能由这些木料长度相加得到的,于是决定在必要的时候把这些木料砍掉一部分以后再使用.不过由于John比较节约,他给自己规定:任何一根木料最多只能削短M米.当然,每根木料削去的木料长度不需要都一样.不过由于测量工具太原始,John只能准确的削去整数米