1 条题解

  • 0
    @ 2024-11-11 23:05:03
    //方法1:Dijkstra + 优先级队列 + 链式前向星
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1001;
    const double inf = 1.08e16;
    struct Edge {  //定义边的结构体
        int v;     //弧头
        double w;  //权值
        int next;  //指向前一条边
    } edge[N * N];
    
    struct Point {
        int x, y;
    };
    
    struct Vertex {   //定义顶点的结构体类型
        int u;        //顶点编号
        double dist;  //起点到当前点的距离
        //若顶点a的dist值大于顶点b的dist值
        //则a的优先级低于b
        bool operator<(const Vertex& b) const { return dist > b.dist; }
    };
    priority_queue<Vertex> pq;
    int head[N], vis[N];
    double dist[N];
    int n, m, cnt, s, t;
    void add(int u, int v, double w) {
        edge[++cnt].v = v;
        edge[cnt].w = w;
        edge[cnt].next = head[u];
        head[u] = cnt;
    }
    //优先级队列 + BFS
    void dijkstra(int st) {
        memset(dist, 0x43, sizeof(dist));
        memset(vis, 0, sizeof(vis));
        dist[st] = 0;
        Vertex p = {st, 0};  //起点
        pq.push(p);
        while (pq.size()) {
            p = pq.top();
            pq.pop();
            if (vis[p.u]) continue;
            vis[p.u] = true;
            for (int i = head[p.u]; i; i = edge[i].next) {
                int v = edge[i].v;
                double w = edge[i].w;
                if (!vis[v] && dist[v] > dist[p.u] + w) {
                    dist[v] = dist[p.u] + w;  //松弛操作
                    pq.push({v, dist[v]});
                }
            }
        }
    }
    
    int main() {
        cin >> n;
        Point pt[n + 1];
        for (int i = 1; i <= n; i++) {
            cin >> pt[i].x >> pt[i].y;
        }
        cin >> m;
        while (m--) {
            int i, j;
            cin >> i >> j;
            double px = pow(double(pt[i].x - pt[j].x), 2);
            double py = pow(double(pt[i].y - pt[j].y), 2);
            double w = sqrt(px + py);
            add(i, j, w);
            add(j, i, w);
        }
        cin >> s >> t;
        dijkstra(s);
        printf("%.2lf\n", dist[t]);
        return 0;
    }
    
    //方法2:Dijkstra + 邻接表
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 105;
    struct Edge {
        int to;
        double w;
    };
    
    vector<Edge> G[N];
    
    struct Node {
        int u;
        double dist;
        bool operator<(const Node& nd) const { return dist > nd.dist; }
    };
    struct Point {
        double x, y;
    };
    priority_queue<Node> pq;
    bool vis[N];
    double dist[N];
    int n, m, cnt, s, t;
    void dijkstra(int st) {
        memset(dist, 0x43, sizeof(dist));
        memset(vis, 0, sizeof(vis));
        dist[st] = 0;
        Node p = {st, 0};
        pq.push(p);
        while (pq.size()) {
            int u = pq.top().u;
            pq.pop();
            if (vis[u]) continue;
            vis[u] = true;
            for (int i = 0; i < G[u].size(); i++) {
                int v = G[u][i].to;
                double w = G[u][i].w;
                if (!vis[v] && dist[v] > dist[u] + w) {
                    dist[v] = dist[u] + w;
                    pq.push({v, dist[v]});
                }
            }
        }
    }
    
    int main() {
        int n;
        cin >> n;
        Point pt[n + 1];
        for (int i = 1; i <= n; i++) {
            cin >> pt[i].x >> pt[i].y;
        }
        cin >> m;
        while (m--) {
            int i, j;
            cin >> i >> j;
            double px = pow(double(pt[i].x - pt[j].x), 2);
            double py = pow(double(pt[i].y - pt[j].y), 2);
            double w = sqrt(px + py);
            G[i].push_back({j, w});
            G[j].push_back({i, w});
        }
        cin >> s >> t;
        dijkstra(s);
        printf("%.2lf\n", dist[t]);
    }
    
    //方法3:SPFA + 链式前向星
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 3e4 + 1;
    const double inf = 0x43;
    struct Edge {
        int v, next;
        double w;
    } edge[N];
    int vis[N], head[N], cnt, n, m, s, t;
    double dist[N];
    
    struct Point {
        int x, y;
    };
    
    void add(int u, int v, double w) {
        edge[++cnt].v = v;
        edge[cnt].w = w;
        edge[cnt].next = head[u];
        head[u] = cnt;
    }
    
    void SPFA(int s) {
        memset(dist, inf, sizeof(dist));
        queue<int> q;
        q.push(s);   //先加入结点
        dist[s] = 0;  //记录路径
        vis[s] = 1;  //统计该点已经搜索过
        while (q.size()) {
            int u = q.front(); q.pop();
            vis[u] = 0; //清除标记
            for (int i = head[u]; i; i = edge[i].next){
                int v = edge[i].v;
                double w = edge[i].w;
                if (dist[v] > dist[u] + w) { //松弛操作
                    dist[v] = dist[u] + w;
                    if(vis[v]) continue;
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
    
    int main() {
        cin >> n;
        Point pt[n + 1];
        for (int i = 1; i <= n; i++) {
            cin >> pt[i].x >> pt[i].y;
        }
        cin >> m;
        while (m--) {
            int i, j;
            cin >> i >> j;
            double px = pow(double(pt[i].x - pt[j].x), 2);
            double py = pow(double(pt[i].y - pt[j].y), 2);
            double w = sqrt(px + py);
            add(i, j, w);
            add(j, i, w);
        }
        cin >> s >> t;
        SPFA(s);
        printf("%.2lf\n", dist[t]);
        return 0;
    }
    
    //方法4:SPFA + 邻接表
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 3e4 + 1;
    const double inf = 0x43;
    struct Node {
        int v;
        double w;
    };
    
    struct Point {
        int x, y;
    };
    
    int vis[N], n, m, s, t;
    double dist[N];
    vector<Node> G[N];
    
    void SPFA(int s) {
        memset(dist, inf, sizeof(dist));
        queue<int> q;
        q.push(s);   //先加入结点
        dist[s] = 0;  //记录路径
        vis[s] = 1;  //统计该点已经搜索过
        while (q.size()) {
            int u = q.front(); q.pop();
            vis[u] = 0; //清除标记
            for (int i = 0; i<G[u].size(); i++) {
                int v = G[u][i].v;
                double w = G[u][i].w;
                if (dist[v] > dist[u] + w) { //松弛操作
                    dist[v] = dist[u] + w;
                    if(vis[v]) continue;
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
    
    int main() {
        cin >> n;
        Point pt[n + 1];
        for (int i = 1; i <= n; i++) {
            cin >> pt[i].x >> pt[i].y;
        }
        cin >> m;
        while (m--) {
            int i, j;
            cin >> i >> j;
            double px = pow(double(pt[i].x - pt[j].x), 2);
            double py = pow(double(pt[i].y - pt[j].y), 2);
            double w = sqrt(px + py);
            G[i].push_back({j, w});
            G[j].push_back({i, w});
        }
        cin >> s >> t;
        SPFA(s);
        printf("%.2lf\n", dist[t]);
        return 0;
    }
    
    
    
    • 1

    信息

    ID
    820
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    10
    已通过
    3
    上传者