猛地一看,这是啥啊????
思索了一下下,发现,嗯,这是一张最短路,我们不需要记录边权,只需要在更新到这个点时,加上点权就好
然后如何处理危险城市呢?用dfs遍历并记录深度,然后更改点权
最后两点比较重要的,记得开longlong&&记得给终点的点权附成0
代码
//By AcerMo
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=700500;
const long long INF=922337203685477580;
int n,m,c1,c2,k,s;
long long int dis[M];
int lev[M],vis[M],dan[M],dou[M],cn[M];
vector<int>v[M];
struct PY
{
int to;
long long int cost;
bool friend operator < (PY a,PY b)
{
return a.cost>b.cost;
}
};
int dfs(int x)
{
if (lev[x]==s) return 0;
for (int i=0;i<v[x].size();i++)
{
if (lev[x]+1<lev[v[x][i]]&&!dou[v[x][i]])
{
lev[v[x][i]]=lev[x]+1;
cn[v[x][i]]=c2;
dfs(v[x][i]);
}
}
return 0;
}
int spfa_py(int x)
{
fill(dis,dis+n+1,INF);
fill(vis,vis+n+1,0);
priority_queue<PY>q;
dis[x]=0;
vis[x]=1;
PY now;
now.cost=dis[x];
now.to=x;
q.push(now);
while (q.size())
{
now=q.top();
q.pop();
vis[now.to]=0;
for (int i=0;i<v[now.to].size();i++)
{
int go=v[now.to][i];
if (dis[go]>cn[go]+dis[now.to]&&!dou[go])
{
dis[go]=cn[go]+dis[now.to];
if (!vis[go])
{
vis[go]=1;
PY t;
t.to=go;
t.cost=dis[go];
q.push(t);
}
}
}
}
}
int read()
{
int x=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
int main()
{
n=read();m=read();k=read();s=read();
c1=read();c2=read();
for (int i=2;i<n;i++) cn[i]=c1;
for (int i=1;i<=k;i++) dan[i]=read(),dou[dan[i]]=1;
for (int i=1;i<=m;i++)
{
int a,b;
a=read();b=read();
v[a].push_back(b);
v[b].push_back(a);
}
fill(lev,lev+n+1,M);
for (int i=1;i<=k;i++)
{
lev[dan[i]]=0;
dfs(dan[i]);
}
cn[n]=0;
spfa_py(1);
cout<<dis[n];
return 0;
}