我的笔记之A1003 Emergency

我的思路

很明显很套路的Dijkstra+DFS

AC代码+AC前代码中存在的问题

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int inf = 999999999;

int weight[505]={0};
int dis[505];
int e[505][505];
bool visit[505]={false};
vector<int> pre[505];
int maxw=0,cnt=0,w=0;


void dfs(int v,int begin){
    w+=weight[v];
    if(v==begin){
        cnt++;
        if(maxw<w)  maxw=w;
        w-=weight[v];
        return; 
    }
    for(int i=0;i<pre[v].size();i++){
        dfs(pre[v][i],begin);
    }
    w-=weight[v];
}

int main(){
    fill(dis,dis+505,inf);
    fill(e[0],e[0]+505*505,inf);
    int n,m,begin,end;
    int a,b,d;
    scanf("%d%d%d%d",&n,&m,&begin,&end);
    for(int i=0;i<n;i++){
        scanf("%d",&weight[i]);
    }

    for(int i=0;i<m;i++){
        scanf("%d%d%d",&a,&b,&d);
        e[a][b] = e[b][a] = d;
    }

    dis[begin]=0;
    for(int i=0;i<n;i++){
        int u=-1,minn=inf;
        for(int j=0;j<n;j++){
            if(visit[j]==false&&dis[j]<minn){//if里面一开始写的是i
                u=j;
                minn=dis[j];
            }
        }
        if(u==-1)   break;
        visit[u]=true;//这一句漏了
        for(int v=0;v<n;v++){
            if(visit[v]==false&&e[u][v]!=inf){
                if(dis[u]+e[u][v]<dis[v]){
                    dis[v] = dis[u]+e[u][v];//这一句漏了
                    pre[v].clear();
                    pre[v].push_back(u);
                }
                else if(dis[u]+e[u][v]==dis[v]){
                    pre[v].push_back(u);
                }
            }
        }
    }
    dfs(end,begin);
    printf("%d %d",cnt,maxw);
    return 0;
}

这道题目思路很套路,我的问题主要是Dijkstra写法很不熟练,写错的代码也全部是在D算法中

  1. 在D算法中找到当前unvisit的点中最近的那个的for循环时,重复使用了主循环的变量i,应该使用另一循环变量如j。发现问题之后改了for中的i为j,又没改for内部的i为j,要注意!
  2. 找到最近的点之后没有标记为true,漏了
 visit[u]=true;
  1. 更新距离时又漏了这句
dis[v] = dis[u]+e[u][v];

教训

Dijkstra算法一定要熟练熟练不能出错!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值