最短路28分求助(码风良好带注释)
查看原帖
最短路28分求助(码风良好带注释)
822239
ncwzdlsd楼主2023/2/5 13:33

码风良好带注释

33 RE,22 WA,22 AC

#include <bits/stdc++.h>
using namespace std;

const long long INF=6000000000000;
const int maxn=200005;
long long to[maxn<<1],v[maxn<<1],head[maxn],nxt[maxn<<1],dis[maxn]/*最短路*/,N,M,K,S,P,Q,cnt,a,b,c;
bool inqueue[maxn],zombie[maxn];//inqueue记录是否在优先队列中,zombie记录是否被僵尸占领
priority_queue<pair<long long,long long> > q1;//优先队列优化Dijkstra
queue<long long> q2;//find用队列,存储危险城市和僵尸占领的城市

void add(int x,int y)
{
    to[++cnt]=y;
    nxt[cnt]=head[x];
    head[x]=cnt;
}

void find(int sss)
{
    while(q2.size())
    {
        int xx=q2.front();q2.pop();
        if(dis[xx]==sss) continue;//已经到达僵尸占领的城市可以影响到的最远城市
        for(int i=head[xx];i;i=nxt[i])
        {
            int yy=to[i];
            if(!dis[yy]) {dis[yy]=dis[xx]+1;q2.push(yy);}
        }
    }
    for(int i=1;i<=cnt;i++)//对每个城市计算边权
    {
        int yy=to[i];
        if(yy==N) continue;//终点边权为0
        if(zombie[i]!=0) continue;//僵尸城
        if(dis[yy]==0) v[i]=P;//安全城市
        else v[i]=Q;//危险城市
    }
}

void dij(int ss)
{
    for(int i=1;i<=N;i++) dis[i]=INF;
    q1.push(make_pair(0,ss));dis[ss]=0;//起点入队,起点到自己的距离为0
    while(q1.size())
    {
        int xx=q1.top().second;q1.pop();
        if(inqueue[xx]) continue;
        inqueue[xx]=1;
        for(int i=head[xx];i;i=nxt[i])
        {
            int yy=to[i],gg=v[i];
            if(dis[yy]>dis[xx]+gg&&zombie[yy]!=1) 
            {dis[yy]=dis[xx]+gg;q1.push(make_pair(-dis[yy],yy))/*用相反数,把优先队列从大顶堆转化为小顶堆*/;}
        }
    }
}

int main()
{
    cin>>N>>M>>K>>S;cin>>P>>Q;
    for(int i=1;i<=K;i++) {cin>>a,zombie[a]=1,q2.push(a);}
    for(int i=1;i<=M;i++) {cin>>b>>c,add(b,c),add(c,b);}
    find(S),dij(1);
    cout<<dis[N];
    return 0;
}
2023/2/5 13:33
加载中...