[算法]PAT-A_1003_邻接矩阵+最短路径+Dijkstra

更新内容:

源程序的算法理解之后,用例只对了一个,经过排查发现是fill()和memset()的用法不清造成的。

//fill()按照单元赋值,将一个区间内的元素都赋同一个值,使用的话需要algorithm头文件
//memset()是按照字节填充内容,在头文件cstring中
//因此memset一般都是用来填充char型数组的,对于int类型数组只能填充0或者-1
//而fill对于int型数组则更加方便一些
//例如:

int num[maxn];
fill(num, num+maxn, 100);
//则将num数组的每个元素都填充为100

vector<int> vec;
fill(vec.begin(), vec.end(), 1000);

//对于memset,下面的方法也是可以的

int num[maxn];
memset(num, 0, sizeof(num));

源程序如下:

//该题是经典模板题,终于将dijkstra理清了
//题目给出的输入数据是顶点数n,边数m,起始顶点和目标顶点st\ed
//给出每条路的端点和路径长度,为int类型
//以及一组顶点权重,最后求st到ed的最短路径条数和所得到顶点权值和的最大值
//核心就是dijstra算法
//尝试一下
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int maxv = 550;
const int INF = 1000000000;

int d[maxv];
int num[maxv];
int w[maxv];

int n, m, st, ed;
int weight[maxv];
bool vis[maxv] = {false};
int G[maxv][maxv];

void Dijkstra(int st){
    //Initialization
    //memset(d, INF, sizeof(d));
    fill(d, d+maxv, INF);
    memset(num, 0, sizeof(num));
    memset(w, 0, sizeof(w));
//错误主要处在fill 和memset上
    d[st] = 0;
    num[st] = 1;
    w[st] = weight[st];

    for(int i=0;i<n;i++){
        int u = -1, min_dis = INF;

        for(int j=0;j<n;j++){
            if(vis[j]==false && d[j]<min_dis){
                u = j;
                min_dis = d[j];
            }
        }

        if(u==-1) return;
        vis[u] = true;
        //这句千万不要忘记,将当前轮得到的最短路径真值所对应的点加入到完成点集中

        for(int v=0;v<n;v++){
            if(vis[v]==false && G[u][v]!=INF){
                if(d[u]+G[u][v]<d[v]){
                    d[v] = d[u] + G[u][v];
                    w[v] = w[u] + weight[v];
                    num[v] = num[u];
                }
                else if(d[u]+G[u][v]==d[v]){
                    if(w[u]+weight[v]>w[v]){
                        w[v] = w[u] + weight[v];
                    }
                    num[v] += num[u];
                }
            }
        }
    }
}

int main(){
    fill(G[0], G[0] + maxv*maxv, INF);
    scanf("%d%d%d%d", &n, &m, &st, &ed);
    for(int i=0;i<n;i++){
        scanf("%d", &weight[i]);
    }

    for(int i=0;i<m;i++){
        int begin_, end_;
        scanf("%d%d", &begin_, &end_);
        scanf("%d", &G[begin_][end_]);
        G[end_][begin_] = G[begin_][end_];
    }
    Dijkstra(st);
    printf("%d %d\n", num[ed], w[ed]);
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值