最新文章
这里会显示最新的几篇文章摘要。
记录生活,分享知识,与你一起成长。
这里会显示最新的几篇文章摘要。
分数 25
作者 rea_lity
单位 成都信息工程大学
ShallowMaple 和 YFffffff 发现今年的算法题目过于的 刁难 我们的算法选手,于是他们两个想打电话来通知 rea_lity 修改题目的难度。要对我们的 蒜金(算法竞赛) 选手更加的友好。众所周知,电话信号要被传输到由基站建成的网络,而网络的传输需要一定的时间。当然,基站内部处理数据也需要一定的时间。
当 rea_lity 接到这个消息的时候,思考到一个问题:
问题为,ShallowMaple 和 YFffffff 打电话过来所消耗的时间 最短 是多少,又有多少种不同的 最短 时间路径呢?
4 51 41 2 3 11 2 10001 2 12 3 13 4 11 4 8
92
明显最短路问题,使用链式前向星存边,再用Dijkstra算法求最短路,用队列优先优化时间为\((mlogm)\)
#include<bits/stdc++.h>
using namespace std;
const int N = 4e5+5; //注意双向边!!!!!!!!!!!!!!!!所以应该有4e5
int head[N],idx;
struct edge{ //边
int to, w, nxt;
edge(){}
edge(int to, int w, int nxt):to(to), w(w), nxt(nxt){}
};
bool vis[N]; //标记
int dis[N]; //距离数组
struct Node //节点
{
int pos, dis;
Node(){}
Node(int pos, int dis):pos(pos), dis(dis){}
bool operator < (const Node& a) const{
return dis > a.dis;
}
/* data */
};
priority_queue<Node> q; //队里优先
int n, m , sta, ed;
edge e[N];
inline void add(int u, int to, int w){
e[++idx] = {to, w, head[u]};
head[u] = idx;
}
int ways[N], wig[N];
void djs(){ //dijsktra
memset(dis, 0x3f, sizeof(dis)); //距离初始化大
dis[sta] = 0;
ways[sta] = 1;
q.push({sta, 0});
while(!q.empty()){
Node t = q.top();
q.pop();
int pos = t.pos;
if(vis[pos]) continue; //如果已经进出过队了,就不会再成为最短节点
vis[pos] = true; //标记已经成为了最短的节点
for(int i = head[pos];i ; i = e[i].nxt){ //遍历
int to = e[i].to;
if(!vis[to] && dis[pos]+e[i].w < dis[to]){ //没有成为过最短节点,进行松弛操作
dis[to] = dis[pos] + e[i].w;
ways[to] = ways[pos];
q.push({to, dis[to]}); //最短节点候选
}
else if (dis[to] == dis[pos]+e[i].w){ //距离相等,路径数相加
ways[to] += ways[pos];
}
}
}
}
int main(){
cin >> n >> m >> sta >> ed;
for(int i = 1;i <= n; ++i) cin >> wig[i];
for(int i = 1;i <= m; ++i){
int a, b, t;
cin >> a >> b >> t;
add(a, b, t+wig[b]);
add(b, a, t+wig[a]); //双向边
}
djs();
cout << dis[ed] << '\n' << ways[ed];
}