我的思路
很明显很套路的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算法中
- 在D算法中找到当前unvisit的点中最近的那个的
for
循环时,重复使用了主循环的变量i
,应该使用另一循环变量如j
。发现问题之后改了for中的i为j,又没改for内部的i为j,要注意! - 找到最近的点之后没有标记为true,漏了
visit[u]=true;
- 更新距离时又漏了这句
dis[v] = dis[u]+e[u][v];
教训
Dijkstra算法一定要熟练熟练不能出错!