//在查找迪杰斯特拉 优先级做法的时候看到了 优先队列优化的dijkstra不是万能的!的L2-001 紧急救援 (25分)题
主要有以下错误:
1.必须采用优先队列 并需要按路径大小排序(即pair需要些cmp函数才可实现)
2.
if (d[v] != p.first)
continue;//因为每次松弛操作后,要删除堆中原有的节点,这样很不方便,所以就加上这一句话判断是否被删除过。
需要加visit标记,否则可能有一条路径多次寻找到
#include<iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
void printPath(int si);
struct edge{
int to;
int cost;
};
typedef pair<int,int> P;
vector<edge> e[1005];
int peo[1005];
int peo2[1005];
int d[1005];
int pre[1005];
int next2[1005];
int n,m,s,di;
int Num[1005];
bool visit[1005];
struct cmp
{
bool operator()(const P p1, const P p2)
{
return p1.first > p2.first; //距离小值优先
}
};
void dijkstra(int s, int end)
{
memset(visit,false,sizeof(visit));
fill(d,d+n,2140000);
d[s]=0;Num[s]=1;
priority_queue<P, vector<P>, cmp> que;
que.push(P(0,s));
while (!que.empty())
{
P p=que.top();que.pop();
int v=p.second;
if(visit[v]) continue;
visit[v]=true;
if (d[v]<p.first)
continue;//因为每次松弛操作后,要删除堆中原有的节点,这样很不方便,所以就加上这一句话判断是否被删除过。
//cout<< "用" << v << "为起点:" << endl;
for (int i=0;i<e[v].size();i++){
edge tmp=e[v][i];
if (d[tmp.to]==d[v]+tmp.cost){
Num[tmp.to]+=Num[v];
if (peo2[tmp.to]<peo2[v]+peo[tmp.to]){
que.push(P(d[tmp.to],tmp.to));
peo2[tmp.to]=peo2[v]+peo[tmp.to];
pre[tmp.to]=v;
// cout << tmp.to << "入栈," << d[tmp.to] << endl;
}
}
if (d[tmp.to]>d[v]+tmp.cost)
{
Num[tmp.to]=Num[v];
d[tmp.to]=d[v]+tmp.cost;
//cout << tmp.to << "入栈," << d[tmp.to] << endl;
que.push(P(d[tmp.to],tmp.to));
peo2[tmp.to]=peo2[v]+peo[tmp.to];
pre[tmp.to]=v;
}else{
//cout << tmp.to << "buxuyao入栈," << d[tmp.to] << endl;
}
if(tmp.to == end){
// printPath(end);
}
}
}
}
void printPath(int di){
int tmp2=di;
int j=1;
next2[0]=tmp2;
while (tmp2!=s){
tmp2=pre[tmp2];
next2[j++]=tmp2;
}
for (int i=j-1;i>0;i--)
printf("%d ",next2[i]);
printf("%d\n",di);
}
int main()
{
memset(Num,0,sizeof(Num));
scanf("%d%d%d%d",&n,&m,&s,&di);
for (int i=0;i<n;i++)
{
scanf("%d",&peo[i]);
peo2[i]=peo[i];
}
for (int i=0;i<m;i++)
{
edge tmp;int start,x1,x2;
scanf("%d%d%d",&start,&x1,&x2);
tmp.to=x1;tmp.cost=x2;
e[start].push_back(tmp);
tmp.to=start;tmp.cost=x2;
e[x1].push_back(tmp);
}
dijkstra(s, di);
printf("%d %d\n",Num[di],peo2[di]);
printPath(di);
return 0;
}