链接
https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376
题解
先求最短路
求完最短路会声生成一张DAG,在这个DAG上做DP统计下路径条数就完了
代码
#include <bits/stdc++.h>
#define ll long long
#define eps 1e-8
#define maxn 1000010
#define base 1000000000ll
#define cl(x) memset(x,0,sizeof(x))
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define dinf 1e100
#define maxlen 1000
using namespace std;
ll N, M, S, T, head[maxn], to[maxn], nex[maxn], w[maxn], dis[maxn], mark[maxn], etot, C[maxn], rd[maxn], f[maxn];
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
ll adde(ll a, ll b, ll v){to[++etot]=b;w[etot]=v;nex[etot]=head[a];head[a]=etot;}
void dijkstra()
{
ll i, mn, x, j, p;
for(i=1;i<=N;i++)dis[i]=linf;
dis[S]=base-1-C[S];
for(i=1;i<=N;i++)
{
mn=linf;
for(j=1;j<=N;j++)
if(!mark[j])
if(dis[j]<mn)mn=dis[j], x=j;
mark[x]=1;
for(p=head[x];p;p=nex[p])
dis[to[p]]=min(dis[to[p]],dis[x]+w[p]);
}
}
void calc()
{
ll i, j, p, x;
for(i=1;i<=N;i++)
for(p=head[i];p;p=nex[p])
if(dis[to[p]]/base==(dis[i]+w[p])/base)rd[to[p]]++;
queue<ll> q;
q.push(S), f[S]=1;
while(!q.empty())
{
x=q.front(), q.pop();
for(p=head[x];p;p=nex[p])
if(dis[to[p]]/base==(dis[x]+w[p])/base)
{
f[to[p]]+=f[x];
rd[to[p]]--;
if(rd[to[p]]==0)q.push(to[p]);
}
}
}
void init()
{
ll i, x, y, z;
N=read(), M=read(), S=read()+1, T=read()+1;
for(i=1;i<=N;i++)C[i]=read();
for(i=1;i<=M;i++)x=read()+1, y=read()+1, z=read(), adde(x,y,z*base-C[y]), adde(y,x,z*base-C[x]);
}
int main()
{
init();
dijkstra();
calc();
printf("%lld %lld",f[T],base-1-dis[T]%base);
return 0;
}