题目链接
思路
- Dijkstra
- 使用
numPath
记录路径数,使用numTeam
记录可以聚集的最多的队数 - 注意:只有找到一个最短的点的时候,才需要入队
#include<bits/stdc++.h>
using namespace std;
const int maxn=505;
struct Edge{
int to,length;
Edge(int t,int l):to(t),length(l){}
};
struct Point{
int id,dis;
Point(int i,int d):id(i),dis(d){}
bool operator<(const Point &p) const{
return dis>p.dis;
}
};
vector<Edge>graph[maxn];
int n,m,c1,c2;
int number[maxn];
int dis[maxn];
int numTeam[maxn];
int numPath[maxn];
void Dijkstra(){
numTeam[c1]=number[c1];
for(int i=0;i<maxn;++i) dis[i]=INT_MAX;
dis[c1]=0;
numPath[c1]=1;
priority_queue<Point>q;
q.push(Point(c1,0));
while(!q.empty()){
int from=q.top().id;
q.pop();
for(int i=0;i<graph[from].size();++i){
int to=graph[from][i].to;
int length=graph[from][i].length;
if(dis[to]>dis[from]+length){
numTeam[to]=numTeam[from]+number[to];
numPath[to]=numPath[from];
dis[to]=dis[from]+length;
q.push(Point(to,dis[to]));
}else if(dis[to]==dis[from]+length){
numTeam[to]=max(numTeam[to],numTeam[from]+number[to]);
numPath[to]+=numPath[from];
}
}
}
printf("%d %d\n",numPath[c2],numTeam[c2]);
}
int main(){
scanf("%d%d%d%d",&n,&m,&c1,&c2);
for(int i=0;i<n;++i) scanf("%d",&number[i]);
int from,to,length;
for(int i=0;i<m;++i){
scanf("%d%d%d",&from,&to,&length);
graph[from].push_back(Edge(to,length));
graph[to].push_back(Edge(from,length));
}
Dijkstra();
system("pause");
return 0;
}