其實想到方法了,但是以為複雜度炸了,好蠢
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
int n,m,rk[30005],f[30005],g[30005],dis[30005],ans;
bool vis[30005];
vector<int> s;
struct edge{
int v,w,nx;
}e[300005];
int cnt,hd[30005];
void add(int u,int v,int w){
e[++cnt]=edge{v,w,hd[u]};
hd[u]=cnt;
}
void add_edge(int u,int v,int w){
add(u,v,w);add(v,u,w);
}
struct node{
int u,l;
};
bool operator<(const node&x,const node&y){
return x.l>y.l;
}
void dij(int st){
priority_queue<node> pq;pq.push(node{st,0});
dis[st]=0;
while(!pq.empty()){
int u=pq.top().u;pq.pop();
if(vis[u])continue;
vis[u]=1;ans++;s.pb(u);
for(int i=hd[u];i;i=e[i].nx){
int v=e[i].v;if(vis[v] || f[v]<=dis[u]+e[i].w || dis[v]<=dis[u]+e[i].w)continue;
dis[v]=dis[u]+e[i].w;
pq.push(node{v,dis[v]});
}
}
for(int u:s)g[u]=min(g[u],dis[u]),dis[u]=0x3f3f3f3f,vis[u]=0;
s.clear();
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&rk[i]);
for(int i=1;i<=m;i++){
int u,v,w;scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
}
memset(dis,0x3f,sizeof(dis));
memset(f,0x3f,sizeof(f));
for(int i=10;i>=1;i--){
memset(g,0x3f,sizeof(g));
for(int j=1;j<=n;j++)
if(rk[j]==i)
dij(j);
for(int j=1;j<=n;j++)f[j]=min(f[j],g[j]);
}
printf("%d\n",ans);
return 0;
}