题目链接
D
i
j
k
s
t
r
a
Dijkstra
Dijkstra堆优化的解法
不会请自行百度
#include <bits/stdc++.h>
#define mes(a, b) memset(a, b, sizeof a)
#define pb push_back
typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 1e3 + 20;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
using namespace std;
int head[maxn],vis[maxn],tot = 0;
ll dis[507];
ll b[507]; // 每个点的队伍
ll num[507]; //记录每个点最短路径条数
ll pre[1007]; //记录前驱
ll cnt[507]; //记录最短路一样的最大流量
int n,m,s,e;
struct node{
int to,ne;
ll w;
}edge[500007];
void addedge(int u,int v,ll w){
edge[tot].to = v;
edge[tot].w = w;
edge[tot].ne = head[u];
head[u] = tot++;
}
struct HeapNode{
ll dis;int u;
HeapNode(ll dis = 0,int u = 0) : dis(dis),u(u){}
bool operator <(const HeapNode& a)const{
return dis > a.dis;
}
}a;
void dijk(int x){
for(int i = 1;i <= n;i++) dis[i] = (ll)INF;
dis[x] = 0;
priority_queue<HeapNode>pq;
while(!pq.empty()) pq.pop();
pq.push(HeapNode(0,x));
while(!pq.empty()){ //first distance second point
a = pq.top(); pq.pop();
int u = a.u;
if(vis[u]) continue;
vis[u] = 1;
for(int i = head[u];i != -1;i = edge[i].ne){ //扫描出边
int v = edge[i].to;ll w = edge[i].w; //v: 出边 w: 权值
if(dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
pq.push(HeapNode(dis[v],v));
num[v] = num[u];
pre[v] = u;
cnt[v] = cnt[u] + b[v];
}
else if(dis[v] == dis[u] + w)
{
if(cnt[v] < cnt[u] + b[v])
{
pre[v] = u;
cnt[v] = cnt[u] + b[v];
}
num[v] += num[u];
}
}
}
}
void init(){
mes(head,-1);tot = 0;
}
int main(){
scanf(" %d %d %d %d",&n,&m,&s,&e);
s++; e++;
for(int i = 1; i <= n; i++) scanf(" %lld",&b[i]);
init();
for(int i = 1;i <= m;i++){
int u,v;ll w;
scanf("%d %d %lld",&u,&v,&w);
u++; v++;
addedge(u,v,w);
addedge(v,u,w);
}
num[s] = 1;
cnt[s] = b[s];
dijk(s);
printf("%lld %lld\n",num[e],cnt[e]);
vector<int>path;
for(int i = e; i != s; i = pre[i]) path.push_back(i-1);
path.push_back(s-1);
for(int i = path.size()-1; i >= 0; i--)
if(i != path.size()-1) printf(" %d",path[i]);
else printf("%d",path[i]);
return 0;
}