#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
//紧急救援
//1.建图
//2、通关算法求最短路径 地杰斯拉算法
int N,M,S,D;
int mapp[510][510];//邻接矩阵 一定要注意不能用map当数组
int nums[510];//消防员的数目
int Dis[510];//记录最短路径
int cnt[510];//结点i同长路径的条数
int sum[510];//走到i的最短路径的救援队数量总和
int pre[510];//结点i的前一节点的下标
bool used[510]={0};//记录结点是否被访问过
vector<int> path;
void dijkstra(int s){
//初始化
fill(Dis,Dis+N,INF);//fill锟斤拷锟斤拷锟斤拷锟节革拷锟斤拷锟斤拷锟斤拷锟絭ector 锟斤拷值锟斤拷锟节筹拷始锟斤拷
fill(used,used+N,false);
fill(pre,pre+N,-1);//锟斤拷锟斤拷锟斤拷锟斤拷赘锟缴讹拷锟?
Dis[s]=0;//s锟角筹拷始锟斤拷锟?锟斤拷为一直没锟斤拷注锟解到锟斤拷锟斤拷没锟斤拷锟斤拷
sum[s]=nums[s];
cnt[s]=1;
while(1){
//如果没被访问过并且这个点是起点或者这个点到起点的路径是最短的
int v=-1;
//cout<<v<<endl;
for(int u=0;u<N;u++)//锟斤拷锟斤拷
{
if(!used[u]&&(v==-1||Dis[u]<Dis[v]))//锟斤拷锟矫伙拷锟斤拷锟斤拷使锟斤拷锟斤拷锟斤拷锟斤拷锥锟斤拷锟斤拷锟斤拷锟斤拷叹锟斤拷锟叫★拷锟斤拷锟揭伙拷锟?
v=u;//锟津被硷拷录锟斤拷锟斤拷
}
if(v==-1)
break;//循锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷
used[v]=true;
for(int u=0;u<N;u++){
if(mapp[v][u]==INF)
continue;
if(Dis[u]>Dis[v]+mapp[v][u]){
Dis[u]=Dis[v]+mapp[v][u];
pre[u]=v;
cnt[u]=cnt[v];
sum[u]=sum[v]+nums[u];//就是这里我找了一周,你大爷
}
/*
if(mapp[v][u]==INF)
continue;
if(Dis[u]>Dis[v]+mapp[v][u])
{
Dis[u]=Dis[v]+mapp[v][u];
pre[u]=v;//锟斤拷录前锟斤拷锟叫碉拷
cnt[u]=cnt[v];
sum[u]=sum[v]+nums[u];//锟斤拷锟斤拷路锟斤拷锟斤拷锟斤拷锟接碉拷锟斤拷锟斤拷
}
*/
else{
if(Dis[u]==Dis[v]+mapp[v][u]){
cnt[u]=cnt[u]+cnt[v];
if(nums[u]+sum[v]>sum[u]){//路径相同取消防数多的
sum[u]=nums[u]+sum[v];
pre[u]=v;
}
}
}
}
}
cout<<cnt[D]<<" "<<sum[D]<<endl;
//输出由s到D的
int k=D;
while(k!=s){//这错了
path.push_back(k);//把路径放进vector
k=pre[k];
}
path.push_back(k);
reverse(path.begin(),path.end());
for(int u=0;u<path.size();u++){//遍历输出
if(u!=0) cout<<" ";
cout<<path[u];
}
cout<<endl;
}
int main(){
cin>>N>>M>>S>>D;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
mapp[i][j]=INF;//初始化map
for(int i=0;i<N;i++){
cin>>nums[i];
}
for(int i=0;i<M;i++){
int x,y;
cin>>x>>y;
cin>>mapp[x][y];
mapp[y][x]=mapp[x][y];
}
dijkstra(S);
return 0;
}
Dij
最新推荐文章于 2023-03-14 13:21:08 发布