zoukankan      html  css  js  c++  java
  • 洛谷 P1744 采购特价商品

                洛谷 P1744 采购特价商品

    题目背景

    《爱与愁的故事第三弹·shopping》第一章。

    题目描述

    中山路店山店海,成了购物狂爱与愁大神的“不归之路”。中山路上有n(n<=100)家店,每家店的坐标均在-10000~10000之间。其中的m家店之间有通路。若有通路,则表示可以从一家店走到另一家店,通路的距离为两点间的直线距离。现在爱与愁大神要找出从一家店到另一家店之间的最短距离。你能帮爱与愁大神算出吗?

    输入输出格式

    输入格式:

    共n+m+3行:

    第1行:整数n

    第2行~第n+1行:每行两个整数x和y,描述了一家店的坐标

    第n+2行:整数m

    第n+3行~第n+m+2行:每行描述一条通路,由两个整数i和j组成,表示第i家店和第j家店之间有通路。

    第n+m+3行:两个整数s和t,分别表示原点和目标店

    输出格式:

    仅一行:一个实数(保留两位小数),表示从s到t的最短路径长度。

    输入输出样例

    输入样例#1: 复制
    5
    0 0
    2 0
    2 2
    0 2
    3 1
    5
    1 2
    1 3
    1 4
    2 5
    3 5
    1 5
    输出样例#1: 复制
    3.41

    说明

    100%数据:n<=100,m<=1000

    4.4 晚上,学妹问我这道题,其实是很久之前做的了,刚开始一看题目还以为是DP(背包)  hua ji

    思路:根据每个点的 x,y 坐标 求出每两点间的直线距离(两点间距离公式:sqrt( ( x1-x2 ) * ( x1-x2 ) + ( y1-y2 ) * ( y1-y2 ) ) )

    然后跑一遍SPFA,完事儿

    /*有些地方稍微给学妹改了一下,但大体是没动的,希望学妹不要介意啊      2333*/
    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define MAXN 100000000
    using namespace std;
    double a[101][3], d[1010], b[1010];
    int n, m, x, y, c[1010][3], Q, W;
    int main() {
        cin >> n;
        for(int i = 1; i <= n; i++)
            cin >> a[i][1] >> a[i][2];
        cin >> m;
        for(int i = 1; i <= m; i++)
            d[i] = MAXN, c[i][1] = MAXN, c[i][2] = MAXN;
        for(int i = 1; i <= m; i++) {
            cin >> x >> y, c[i][1] = x, c[i][2] = y;
            b[i] = sqrt(pow(a[x][1]-a[y][1], 2) + pow(a[x][2]-a[y][2], 2));
        }
        cin >> Q >> W;
        d[Q] = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(d[c[j][1]]+b[j] < d[c[j][2]]) d[c[j][2]] = d[c[j][1]]+b[j];
                if(d[c[j][2]]+b[j] < d[c[j][1]]) d[c[j][1]] = d[c[j][2]]+b[j];
            }
        }
        printf("%.2f", d[W]);
        return 0;
    }
    学妹的代码

    突然发现有些看不懂学妹的代码 2333 (放假回来让学妹讲讲)

    #include<algorithm>
    #include<cstring>
    #include<utility>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define M 10005
    #define MAXN 0x7fffffff
    using namespace std;
    queue<int> q;
    pair<int, int> pa[105];        //存边的横(first)纵(second)坐标
    int n, m;
    int tot;
    double dis[M], cap[M];        //开double 确保精度
    int to[M], net[M], head[M], vis[M];
    
    void add(int u, int v, double w) {        //邻接链表存边,这样比用结构体存快一些,因为结构体还需要从里边调出来
        to[++tot] = v; net[tot] = head[u]; head[u] = tot; cap[tot] = w;
        to[++tot] = u; net[tot] = head[v]; head[v] = tot; cap[tot] = w;
    }
    
    void spfa(int x) {        //朴素的spfa
        for(int i = 1; i <= n; i++) dis[i] = 1.0 * MAXN, vis[i] = 0;
        dis[x] = 0.0; vis[x] = 1; q.push(x);
        while(!q.empty()) {
            int y = q.front(); q.pop(); vis[y] = 0;
            for(int i = head[y]; i; i = net[i]) {
                int t = to[i];
                if(dis[t] > dis[y] + cap[i]) {
                    dis[t] = dis[y] + cap[i];
                    if(!vis[t]) vis[t] = 1, q.push(t);
                }
            }
        }
    }
    
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%d%d", &pa[i].first, &pa[i].second);
        scanf("%d", &m);
        for(int i = 1; i <= m; i++) {
            int a, b;
            double c;
            scanf("%d%d", &a, &b);
            c = sqrt(double((pa[a].first-pa[b].first)*(pa[a].first-pa[b].first))+double((pa[a].second-pa[b].second)*(pa[a].second-pa[b].second)));        //精度很重要
            add(a, b, c);        //在两点间有通路的情况下求两点间距离、存边
        }
        int s, tmp;
        scanf("%d%d", &s, &tmp);
        spfa(s);
        printf("%.2lf",dis[tmp]);
        return 0;
    }
    既然看不懂学妹的,那就好好写题解吧
  • 相关阅读:
    alter table move
    VI常用命令
    【转】window.showModalDialog以及window.open用法简介
    这算是随想
    SQL Prompt——SQL智能提示插件
    C#和VB.NET中类型相关资料整理
    仿查询分析器的C#计算器——6.函数波形绘制
    Snippet Compiler——代码段编译工具
    仿查询分析器的C#计算器——4.语法分析
    【高效程序员系列】目录
  • 原文地址:https://www.cnblogs.com/v-vip/p/8719566.html
Copyright © 2011-2022 走看看