( m{kkksc03})说是模板题,但像我这种蒟蒻觉得万分艰难
这道题目的核心在于求出所有的危险城市,我们可以一次性将所有的被占领的城市全部加入队列里,然后扩展危险城市
还有一点就是点权最短路,具体看代码吧
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
int read(){
int k=0; char c=getchar();
for(;c<'0'||c>'9';) c=getchar();
for(;c>='0'&&c<='9';c=getchar())
k=k*10+c-48;
return k;
}
bool js[100010];
int pon[100010];
struct zzz{
int t,nex;
}e[200010<<2]; int head[100010],tot;
void add(int x,int y){
e[++tot].t=y;
e[tot].nex=head[x];
head[x]=tot;
}
struct hhh{
int k,len;
};
queue <hhh> q; queue <int> q2;
LL dis[100010]; bool vis[100010],wrning[100010];
int main(){
int n=read(),m=read(),k=read(),s=read(),p1=read(),p2=read();
for(int i=1;i<=k;i++){
int x=read(); q.push(hhh{x,s}); js[x]=1;
wrning[x]=1;
}
for(int i=1;i<=m;i++){
int x=read(),y=read();
add(x,y); add(y,x);
}
while(!q.empty()){ //扩展危险城市
hhh k=q.front(); q.pop();
if(!k.len) continue;
for(int i=head[k.k];i;i=e[i].nex){
if(js[e[i].t]) continue;
js[e[i].t]=1;
q.push(hhh{e[i].t,k.len-1});
}
}
for(int i=2;i<=n-1;i++) pon[i]= (js[i]? p2:p1);
for(int i=1;i<=n+1;i++) dis[i]=(LL)922337203685;
pon[n+1]=(LL)922336854775; dis[1]=0;
q2.push(1); vis[1]=1;
while(!q2.empty()){ //点权最短路
int k=q2.front(); q2.pop(); vis[k]=0;
for(int i=head[k];i;i=e[i].nex){
if(wrning[e[i].t]) continue;
if(dis[e[i].t]>dis[k]+pon[e[i].t]){
dis[e[i].t]=dis[k]+pon[e[i].t];
if(!vis[e[i].t]){
vis[e[i].t]=1; q2.push(e[i].t);
}
}
}
}
cout<<dis[n];
return 0;
}