不难发现每条边都有交通中心 所以对每个交通中心跑一次spfa就好
求答案的时候就枚举是先到哪个交通中心,取个最优值。
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define me(a,x) memset(a,x,sizeof a)
using namespace std;
typedef long long LL;
const int N=20010,K=205;
const int inf=1000000007;
inline LL read()
{
LL x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
struct node{int y,c,next;}a[N]; int first[N],len;
void ins(int x,int y,int c)
{
a[++len].y=y,a[len].c=c,a[len].next=first[x],first[x]=len;
}
queue<int>q;
int f[K][N]; bool v[N];
int p[N];
void spfa(int st)
{
q.push(st); me(v,0);
v[st]=1,f[p[st]][st]=0;
while(!q.empty())
{
int x=q.front();
for(int k=first[x];k;k=a[k].next)
{
int y=a[k].y;
if(f[p[st]][y]>f[p[st]][x]+a[k].c)
{
f[p[st]][y]=f[p[st]][x]+a[k].c;
if(!v[y]){v[y]=1; q.push(y);}
}
}
q.pop();
v[x]=0;
}
}
int main()
{
int k=read(),m=read(),n=read(),q=read();
int x,y,c,i;
for(i=1;i<=m;i++)
{
x=read(),y=read(),c=read();
ins(x,y,c);
}
me(f,63);
for(i=1;i<=n;i++)
{
x=read();
p[x]=i; spfa(x);
}
LL ans=0; int s=0;
while(q--)
{
x=read(),y=read();
LL g=inf;
if(!p[x])
for(i=first[x];i;i=a[i].next)
g=min(g,(LL)a[i].c+f[p[a[i].y]][y]);
else g=f[p[x]][y];
if(g<inf)s++,ans+=g;
}
printf("%d\n%lld\n",s,ans);
return 0;
}