zoukankan      html  css  js  c++  java
  • UVA1001 Say Cheese(Dijkstra或Floyd)

    题目链接:UVA1001

    题意:在一个巨大奶酪中的A要以最短的时间与B相遇。在奶酪中走一米的距离花费的时间是10s,而奶酪中有许多洞,穿过这些洞的时间是0s。给出A、B以及各个洞的坐标,求最短的时间。

    三维??乖乖,这怎么用最短路算法。在搜了题解后才知道可以编号压缩成二维啊,这操作骚气,实在想不出来啊!!

    思路:将起点,终点,各个洞进行编号看成一个一个的点,写一个函数求出各个点之间的距离(即边的权值),在运用dijstra或Floyd算法就可以了。Ps:求距离的时候可以将各个点看成一个一个的球,距离就是两球心之间的距离减去两个球的半径和。

    数据类型要用double,WA到吐得节奏。

    Floyd方法:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <string>
    #include <queue>
    #include <map>
    #define INF 0x3f3f3f3f
    #define FRE() freopen("in.txt","r",stdin)
    
    using namespace std;
    typedef long long ll;
    const int maxn = 110;
    int n;
    double d[maxn][maxn];
    struct H
    {
        double x;
        double y;
        double z;
        double r;
    }hole[maxn];
    
    double dist(H &a,H &b)
    {
        double x = (a.x-b.x)*(a.x-b.x);
        double y = (a.y-b.y)*(a.y-b.y);
        double z = (a.z-b.z)*(a.z-b.z);
        if(sqrt(x+y+z) - a.r - b.r > 0.0)
            return sqrt(x+y+z) - a.r - b.r;
        else
            return 0.0;
    }
    
    
    
    int main()
    {
       // FRE();
        int cnt = 0;
        while(scanf("%d",&n) && n != -1)
        {
            for(int i = 0; i < n; i++)
            {
                scanf("%lf%lf%lf%lf",&hole[i].x,&hole[i].y,&hole[i].z,&hole[i].r);
            }
            scanf("%lf%lf%lf",&hole[n].x,&hole[n].y,&hole[n].z);
            scanf("%lf%lf%lf",&hole[n+1].x,&hole[n+1].y,&hole[n+1].z);
    
            hole[n].r = hole[n+1].r = 0;
    
            for(int i = 0; i <= n+1; i++)
            for(int j = 0; j <= n+1; j++)
            {
                if(i == j)
                    d[i][j] = 0;
                else
                    d[i][j] = INF;
            }
            for(int i = 0; i < n+2; i++)
            for(int j = 0; j < n+2; j++)
                if(i != j) d[i][j] = dist(hole[i],hole[j]);
    
            for(int k = 0; k < n+2; k++)
            for(int i = 0; i < n+2; i++)
            for(int j = 0; j < n+2; j++)
            {
                d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
            }
            d[n][n+1] *= 10;
            printf("Cheese %d: Travel time = %.0f sec
    ",++cnt,d[n][n+1]);
        }
        return 0;
    }
    View Code

    Dijkstra邻接矩阵方法:

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #define FRE() freopen("in.txt","r",stdin)
    #define INF 0x3f3f3f3f
    
    using namespace std;
    const int maxn = 300;
    double x[maxn],y[maxn],z[maxn],r[maxn];
    double d[maxn],vis[maxn];
    double mp[maxn][maxn];
    int n;
    
    double dist(int i,int j)
    {
        double tx = (x[i]-x[j])*(x[i]-x[j]);
        double ty = (y[i]-y[j])*(y[i]-y[j]);
        double tz = (z[i]-z[j])*(z[i]-z[j]);
        double res = sqrt(tx + ty + tz) - r[i] - r[j];
        if(res > 0)
            return res;
        else
            return 0;
    }
    
    void Dij()
    {
        memset(vis,0,sizeof(vis));
        for(int i = 0; i <= n+1; i++)
            d[i] = INF;
        d[0] = 0;
        for(int i = 0; i <= n+1; i++)
        {
            int u;double mmin = INF;
            for(int i = 0; i <= n+1; i++)
            {
                if(!vis[i] && d[i] < mmin)
                {
                    mmin = d[i];
                    u = i;
                }
            }
            if(u == n+1) return;
            vis[u] = 1;
            for(int i = 0; i <= n+1; i++)
            {
                d[i] = min(d[i], d[u]+mp[u][i]);
            }
        }
    
    }
    
    int main()
    {
        //FRE();
        int cnt = 0;
        while(scanf("%d",&n) && n != -1)
        {
            for(int i = 1; i <= n; i++)
            {
                scanf("%lf%lf%lf%lf",&x[i],&y[i],&z[i],&r[i]);
            }
            scanf("%lf%lf%lf",&x[0],&y[0],&z[0]);r[0] = 0;
            scanf("%lf%lf%lf",&x[n+1],&y[n+1],&z[n+1]);r[n+1] = 0;
    
            for(int i = 0; i <= n+1; i++)
            {
                for(int j = 0; j <= n+1; j++)
                    mp[i][j] = dist(i,j);
            }
            Dij();
            printf("Cheese %d: Travel time = %.0f sec
    ",++cnt,d[n+1]*10);
    
        }
        return 0;
    }
    View Code

    Dijkstra优先队列方法:vector数组的清空啊,别问我是怎么知道的!!!!!!

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #define FRE() freopen("in.txt","r",stdin)
    #define INF 0x3f3f3f3f
    
    using namespace std;
    typedef pair<double,int> P;
    const int maxn = 300;
    struct H
    {
        double x,y,z;
        double r;
    }hole[maxn];
    struct edge
    {
        int to;
        double cost;
        edge(int t,double c):to(t),cost(c){}
    };
    vector<edge> g[maxn];
    double d[maxn];
    
    
    double dist(H &a,H &b)
    {
        double x = (a.x - b.x)*(a.x - b.x);
        double y = (a.y - b.y)*(a.y - b.y);
        double z = (a.z - b.z)*(a.z - b.z);
        double res = sqrt(x + y + z) - a.r - b.r;
        if(res > 0)
            return res;
        else
            return 0;
    }
    
    int main()
    {
        //FRE();
        int cnt = 0;
        int n;
        while(scanf("%d",&n) && n != -1)
        {
            for(int i = 1; i <= n; i++)
            {
                scanf("%lf%lf%lf%lf",&hole[i].x,&hole[i].y,&hole[i].z,&hole[i].r);
            }
            scanf("%lf%lf%lf",&hole[0].x,&hole[0].y,&hole[0].z); hole[0].r = 0;
            scanf("%lf%lf%lf",&hole[n+1].x,&hole[n+1].y,&hole[n+1].z);hole[n+1].r = 0;
            for(int i = 0; i < n+2; i++) g[i].clear();
            for(int i = 0; i < n+2; i++)
            {
                for(int j = i+1; j < n+2; j++)
                {
                    double t = dist(hole[i],hole[j]);
                    g[i].push_back(edge(j,t));
                    g[j].push_back(edge(i,t));
                }
            }
    
            for(int i = 0; i <n+2; i++)
                d[i] = INF;
            d[0] = 0;
            priority_queue<P, vector<P>, greater<P> > que;
            que.push(P(0,0));
            while(!que.empty())
            {
                P p = que.top();
                que.pop();
                int v = p.second;
                if(d[v] < p.first) continue;
                for(int i = 0; i < g[v].size(); i++)
                {
                    edge ee = g[v][i];
                    if(d[ee.to] > d[v] + ee.cost)
                    {
                        d[ee.to] = d[v] + ee.cost;
                        que.push(P(d[ee.to], ee.to));
                    }
                }
            }
            printf("Cheese %d: Travel time = %.0f sec
    ",++cnt,d[n+1]*10);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    vue mock数据设置
    vue 的全局拦截器
    vue-resource基础介绍
    快速排序
    Node 中的 stream (流)
    v8垃圾回收和js垃圾回收机制
    Node内存限制与垃圾回收
    ReactNative http网络通讯
    luogu1829 [国家集训队]Crash的数字表格
    luogu2870 [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold
  • 原文地址:https://www.cnblogs.com/sykline/p/9737796.html
Copyright © 2011-2022 走看看