[luogu3393]逃离僵尸岛

[luogu3393]逃离僵尸岛

luogu
先把被禁止的点和新建的虚点n+1连0边
跑最短路,dis<=s的点价格为Q,否则为P,
再建图跑最短路

#define ll long long
#include<bits/stdc++.h>
using namespace std;
const int N=100005,M=500005;
int re(){
    int x=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*w;
}
int n,m,k,len,cnt,P,Q;
int h[N],a[M],b[M],val[N];
ll d[N];
bool ban[N],vis[N];
struct node{ll id,d;};
struct edge{int to,next,w;}e[M];
bool operator <(node x,node y){return x.d>y.d;}
priority_queue<node>q;
void link(int u,int v,int w){
    e[++cnt]=(edge){v,h[u],w};h[u]=cnt;
}
void dij(int s){
    memset(vis,0,sizeof(vis));
    memset(d,127,sizeof(d));d[s]=0;
    q.push((node){s,0});
    while(!q.empty()){
        int u=q.top().id;q.pop();
        if(vis[u])continue;vis[u]=1;
        for(int i=h[u];i;i=e[i].next){
            int v=e[i].to;
            if(d[v]>d[u]+e[i].w){
                d[v]=d[u]+e[i].w;
                q.push((node){v,d[v]});
            }
        }
    }
}
int main(){
    n=re(),m=re(),k=re(),len=re();
    P=re(),Q=re();
    for(int i=1,x;i<=k;i++){
        ban[x=re()]=1;
        link(n+1,x,0);
    }
    for(int i=1;i<=m;i++){
        a[i]=re(),b[i]=re();
        link(a[i],b[i],1);
        link(b[i],a[i],1);
    }
    dij(n+1);cnt=0;memset(h,0,sizeof(h));
    for(int i=1;i<=n;i++){
        if(d[i]<=len)val[i]=Q;
        else val[i]=P;
    }
    val[n]=val[1]=0;
    for(int i=1;i<=m;i++)
        if(!ban[b[i]]&&!ban[a[i]]){
            link(a[i],b[i],val[b[i]]);
            link(b[i],a[i],val[a[i]]);
        }
    dij(1);
    printf("%lld
",d[n]);
    return 0;
}
原文地址:https://www.cnblogs.com/sdzwyq/p/9929911.html