三块不一样的石头 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日

悬赏问题

  • ¥200 基于同花顺supermind的量化策略脚本编辑
  • ¥20 Html备忘录页面制作
  • ¥15 黄永刚的晶体塑性子程序中输入的材料参数里的晶体取向参数是什么形式的?
  • ¥20 数学建模来解决我这个问题
  • ¥15 计算机网络ip分片偏移量计算头部是-20还是-40呀
  • ¥15 stc15f2k60s2单片机关于流水灯,时钟,定时器,矩阵键盘等方面的综合问题
  • ¥15 YOLOv8已有一个初步的检测模型,想利用这个模型对新的图片进行自动标注,生成labellmg可以识别的数据,再手动修改。如何操作?
  • ¥30 NIRfast软件使用指导
  • ¥20 matlab仿真问题,求功率谱密度
  • ¥15 求micropython modbus-RTU 从机的代码或库?