第一版代码dfs搜得21分,段错误(应该是递归次数太多)
第二版代码堆优化dijkstra,依然段错误(应该是储存到堆的信息太多?不懂)
然后用了朴素的dijkstra,同时维护最短路的条数、最短路上节点信息之和、最短路径等信息,值得记录学习一下!
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=505,M=N*2;
int h[N],e[M],ne[M],w[M],idx;
int sl[N];
int n,m,st,ed;
bool vis[N];
int g[N][N];
int num[N];//最短路径个数
int sum[N];//最大救援队数量
int dis[N];
int pre[N];
typedef pair<int,int> PII;
void dijkstra()
{
memset(dis,0x3f,sizeof dis);
memset(pre,-1,sizeof pre);
dis[st]=0;
sum[st]=sl[st];//从起点开始初始化最短路信息
num[st]=1;//当前最短路条数为1
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=0;j<n;j++)
if(!vis[j]&&(t==-1||dis[t]>dis[j]))
t=j;
vis[t]=true;
for(int j=0;j<n;j++)
{
if(dis[j]>dis[t]+g[t][j])
{//更新最短路以及信息
dis[j]=dis[t]+g[t][j];
num[j]=num[t];
sum[j]=sum[t]+sl[j];
pre[j]=t;
}
else if(dis[j]==dis[t]+g[t][j])
{//此时需要叠加最短路的条数
num[j]+=num[t];
if(sum[t]+sl[j]>sum[j])
{
sum[j]=sum[t]+sl[j];
pre[j]=t;
}
}
}
}
}
void solve()
{
cout<<num[ed]<<" "<<sum[ed]<<endl;
vector<int> vc;
int x=ed;
do{
vc.push_back(x);
x=pre[x];
}while(x!=-1);
for(int i=vc.size()-1;i>=0;i--)
{
cout<<vc[i];
if(i!=0) cout<<" ";
}
}
int main()
{
cin>>n>>m>>st>>ed;
memset(h,-1,sizeof h);
memset(g,0x3f,sizeof g);
for(int i=0;i<n;i++) cin>>sl[i];
for(int i=0;i<m;i++)
{
int a,b,c;cin>>a>>b>>c;
g[a][b]=g[b][a]=c;
}
dijkstra();
solve();
}