51nod 1459 迷宫游戏 【djstl】

djstl做法:(相继还会跟新其它的优化做法, 现在就到这里)

#include <iostream>
#include <cstdio>
#include <cstring>
#define M 505
#define N 505
using namespace std;
const int inf = 0x3f3f3f3f;

int num[505];       //  结点权值
int map[505][505];  //  图的临近矩阵
int vis[505];       //  结点是否处理过

int ans[505];       //  最短路径结点权值和

int dis[505];       //  各点最短路径花费

int n,m,Start,End;// n结点数,m边数,Start起点,End终点


void Dij(int v){
    ans[v]=num[v];  //将开始值的 分数放入 ans【v】中
    memset(vis,0,sizeof(vis));  //标记数组
    for(int i=0;i<n;++i){
        if(map[v][i]<inf)   ans[i]=ans[v]+num[i];// 开始的分数到每一个地方的分数和=当前v到i的分数和
        dis[i]=map[v][i];                        // 当前v到i的距离
    }
    dis[v]=0;  //记录当前的路径长度为0
    vis[v]=1;  //并且当前开始走的点被访问(不在被访问)
    for (int i=1;i<n;++i){ //遍历每一个值(除了第一个)
        int u=0,min=inf; //u用来确定下一个最近的地点的节点
        for (int j=0;j<n;++j)// min用来筛选最小的值 并确定u的值
            if(!vis[j]&&dis[j]<min) min=dis[u=j];
        vis[u]=1; //节点u被访问过
        for(int k=0;k<n;++k) //更新两个表的值  两个表分别为最短距离表 和 权值表 是否更新-》确定该点是否被访问&&原先到k点的路径长度 比 现在该点(确定了本次的最短节点)+ 该节点到k节点的大 就进行更新
            if(!vis[k]&&dis[k]>map[u][k]+dis[u]){
                dis[k]=map[u][k]+dis[u];
                ans[k]=ans[u]+num[k];
            }
        for(int k=0;k<n;++k)  //如果两个路径相等 则将最大的分值加进ans【k】中
            if(dis[k]==map[u][k]+dis[u])
                ans[k]=max(ans[k],ans[u]+num[k]);
    }
    cout<<dis[End]<<" "<<ans[End]<<endl;  //  输出终点最短路径花费、最短路径结点权值和
}
int main()
{
    cin>>n>>m>>Start>>End;
    for (int i=0;i<n;++i)   cin>>num[i];
    memset(vis,0,sizeof(vis));
    memset(map,0x3f,sizeof(map));
    for (int i=0;i<m;++i){
        int x,y,z;
        cin>>x>>y>>z;
        if (map[x][y]>z) map[x][y]=map[y][x]=z;
    }
    Dij(Start);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值