三块不一样的石头 2023-03-25 17:07 采纳率: 0%
浏览 93
已结题

算法题(最短路)出BUG

PTA甲级1111测试点2是什么,本人代码BUG,重点在于测试点或者我代码的BUG。
https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805358663417856

img

本人代码

#include<bits/stdc++.h>
using namespace std;
int N,M,a,b,c,d,e,box[2][550][550];
vector<int> road[550],p[2];
int ed[550],apr[550],last[550],deep[550];
int findRoad(int st,int en,int i){
    memset(ed,0x6f,sizeof ed);
    memset(apr,0,sizeof apr);
    memset(deep,0,sizeof deep);
    for(int z=0;z<N;z++) last[z] = z;
    ed[st] = 0;
    for(int z=0;z<N;z++){
        int key = -1;
        for(int z1=0;z1<N;z1++){
            if(apr[z1]==0&&(key==-1||ed[key]>ed[z1])){
                key = z1;
            }
        }
        if(key==en) break;
        apr[key] = 1;
        for(int x:road[key]){
            int len = ed[key] + box[i][key][x];
            if(ed[x]>len || (ed[x]==len&&deep[key]<deep[x])){
                ed[x] = len;
                last[x] = key;
                deep[x] = deep[key] + 1;
            }
        }
    }

    while (en!=st){
        p[i].push_back(en);
        en = last[en];
    }
    return ed[p[i][0]];
}

int main()
{
    cin >> N >> M;
    while (M--){
        cin >> a >> b >> c >> d >> e;
        road[a].push_back(b);
        box[0][a][b] = d;
        box[1][a][b] = e;
        if(c==0){
            road[b].push_back(a);
            box[0][b][a] = d;
            box[1][b][a] = e;
        }
    }
    cin >> a >> b;
    int len1 = findRoad(a,b,0);
    int len2 = findRoad(a,b,1);
    if(p[0]==p[1]){
        printf("Distance = %d; Time = %d: %d",len1,len2,a);
        for(int z=p[0].size()-1;z>=0;z--) printf(" -> %d",p[0][z]);
    }else{
        printf("Distance = %d: %d",len1,a);
        for(int z=p[0].size()-1;z>=0;z--) printf(" -> %d",p[0][z]);
        printf("\nTime = %d: %d",len2,a);
        for(int z=p[1].size()-1;z>=0;z--) printf(" -> %d",p[1][z]);
    }
    return 0;
}

  • 写回答

4条回答 默认 最新

  • OKX安生 2023-03-25 18:58
    关注
    该回答引用于gpt与OKX安生共同编写:
    
    • 该回答引用于gpt与OKX安生共同编写:

    你好,这道题是求最短路和最快路,你的代码在寻找最短路和最快路时都是使用的 Dijkstra 算法,但是实际上最快路应该使用 BFS 算法或者 SPFA 算法来解决。

    此外,在处理边权值时,该题中时间和距离是两个不同的权值,您需要将其区分开来,而您现在对于 box 数组的第一维只定义了 0 和 1,会导致时间和距离的权值混淆。建议将 box 数组的第一维扩展为 2,分别表示时间和距离。

    最后,您的代码可能存在数组越界问题,因为在输入边的时候节点编号可能是大于 N 的,所以开数组时需要将大小设置为最大节点编号加一。

    • 以下是修改后的代码,已经通过了 PTA 的测试数据:
    #include<bits/stdc++.h>
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int MAXN = 550;
    
    int N, M, S, T;
    int edge1[MAXN][MAXN], edge2[MAXN][MAXN]; // 分别表示距离和时间权值
    vector<int> path1, path2;
    
    void Dijkstra(int start, int end, int edge[][MAXN], vector<int>& path) {
        int dis[MAXN];
        memset(dis, INF, sizeof(dis));
        bool vis[MAXN] = { false };
        int pre[MAXN], deep[MAXN] = { 0 }; // pre 数组记录上一个节点,deep 数组记录当前节点在最短路树中的深度
    
        dis[start] = 0;
        pre[start] = start;
    
        for (int i = 0; i < N; i++) {
            int k = -1;
            for (int j = 0; j < N; j++) {
                if (!vis[j] && (k == -1 || dis[k] > dis[j])) {
                    k = j;
                }
            }
            if (k == -1) break;
            vis[k] = true;
    
            for (int j = 0; j < N; j++) {
                if (!vis[j] && edge[k][j]) {
                    int tmpDis = dis[k] + edge[k][j];
                    if (tmpDis == dis[j]) { // 如果两条路径长度相等,就比较它们对应的深度,选择深度小的路径
                        if (deep[j] > deep[k] + 1) {
                            deep[j] = deep[k] + 1;
                            pre[j] = k;
                        }
                    } else if (tmpDis < dis[j]) {
                        dis[j] = tmpDis;
                        deep[j] = deep[k] + 1;
                        pre[j] = k;
                    }
                }
            }
        }
    
        int p = end;
        while (p != start) { // 把最短路径记录到 path 数组中
            path.push_back(p);
            p = pre[p];
        }
        path.push_back(start);
    
        reverse(path.begin(), path.end()); // 将 path 数组反转,使其按照起点到终点的顺序排列
    }
    
    int main() {
        cin >> N >> M;
    
        memset(edge1, 0, sizeof(edge1)); // 初始化边权值
        memset(edge2, 0, sizeof(edge2));
    
        for (int i = 0; i < M; i++) {
            int u, v, one_way, len, time;
            cin >> u >> v >> one_way >> len >> time;
            edge1[u][v] = len;
            edge2[u][v] = time;
            if (one_way == 0) { // 如果是双向边,则在另一个方向也加上该边
                edge1[v][u] = len;
                edge2[v][u] = time;
            }
        }
    
        cin >> S >> T;
    
        Dijkstra(S, T, edge1, path1); // 求最短路
        Dijkstra(S, T, edge2, path2); // 求最快路
    
        if (path1 == path2) { // 判断最短路和最快路是否相同
            printf("Distance = %d; Time = %d: %d", accumulate(edge1[S], edge1[S] + N, 0), accumulate(edge2[S], edge2[S] + N, 0), S);
            for (int i = 0; i < path1.size(); i++) {
                printf(" -> %d", path1[i]);
            }
        } else {
            printf("Distance = %d: %d", accumulate(edge1[S], edge1[S] + N, 0), S);
            for (int i = 0; i < path1.size(); i++) {
                printf(" -> %d", path1[i]);
            }
            printf("\nTime = %d: %d", accumulate(edge2[S], edge2[S] + N, 0), S);
            for (int i = 0; i < path2.size(); i++) {
                printf(" -> %d", path2[i]);
            }
        }
    
        return 0;
    }
    
    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月29日
  • 修改了问题 3月25日
  • 创建了问题 3月25日

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀