团体天梯赛-L2-001紧急救援
题目链接:L2-001 紧急救援 (25 分)
题目大意:每个城市有救援队伍的数目,在保证最短路的同时,同时救援队伍人数要尽量多,最后输出从一个点到一个点最短路的条数、最短路径长度和路径。
题解:dfs求路径和堆优化的Dijkstra
//本题用了链式前向星存放图和堆优化求最短路
#include<bits/stdc++.h>
using namespace std;
const int N = 10001;
int n,m,start,End,idx,u,v,w;
int Arr[N],first[N],cnt[N],sum[N],pre[N],dis[N],vis[N];
struct Graphy{
int to;
int weight;
int next;
}G[N];
struct node{
int to;
int weight;
bool operator < (const node &temp) const{
return weight > temp.weight;
}
};
void add(int u,int v,int w){
G[++idx].to = v;
G[idx].weight = w;
G[idx].next = first[u];
first[u] = idx;
}
void Dijkstra(){
fill(dis,dis+N,INT_MAX);
dis[start] = 0;
pre[start] = start;
sum[start] = Arr[start];
priority_queue<node> q;
q.push(node{start,0});
while(!q.empty()){
node top = q.top();
q.pop();
if(vis[top.to]) continue;
vis[top.to] = 1;
for(int i=first[top.to];i!=-1;i=G[i].next){
int t = G[i].to;
if(dis[t]>dis[top.to]+G[i].weight){
dis[t] = dis[top.to] + G[i].weight;
pre[t] = top.to;
cnt[t] = cnt[top.to];
sum[t] = sum[top.to] + Arr[t];
}
else if(dis[t]==dis[top.to]+G[i].weight){
cnt[t]+=cnt[top.to];
if(sum[top.to]+Arr[t]>sum[t]){
sum[t] = sum[top.to] + Arr[t];
pre[t] = top.to;
}
}
if(!vis[t]){
q.push(node{t,dis[t]});
}
}
}
}
void find_path(int s){
if(pre[s]==s){
cout<<s;
return ;
}
find_path(pre[s]);
cout<<" "<<s;
}
int main(){
fill(first,first+N,-1);
fill(cnt,cnt+N,1);
cin>>n>>m>>start>>End;
for(int i=0;i<n;i++) cin>>Arr[i];
for(int i=0;i<m;i++){
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
Dijkstra();
cout<<cnt[End]<<" "<<sum[End]<<endl;
find_path(End);
return 0;
}