P3393 逃离僵尸岛

P3393 逃离僵尸岛

啊。好久不写dij手都生了

这道题就是预先处理出是否是危险城市,然后跑一个最短路就行了

然后因为我感觉这个对时间要求不大紧。判断危险城市时就写了个电风扇(DFS)

然后T飞了呜呜呜~~

//Dan数组是标记一个城市是否是危险城市
void danger(int now,int dist)
{
    if(dist>s)	return ;
    if(!Dan[now])	Dan[now]=1;
    if(!dist)	Dan[now]=-1;//-1表示感染城市
    for(int i=head[now];i;i=line[i].nxt)
        danger(line[i].p,dist+1);
}

然后又怒改了一波百分数(BFS)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using std::swap;
using std::queue;
const int N=101000,M=202000;
struct Data
{
	int p;
	long long dis;
	bool operator < (const Data &a)const 
	{
		return dis<a.dis;
	}
};
struct Link
{
	int p;
	int nxt;
};
Data base[M<<3];
Link line[M<<1];
int head[N],tail;
int n,m,k,s,p,q,len;
int zombie[N];
int Dan[N];
long long dis[N];
bool get[N];
Data top()
{
	return base[1];
}
void push(Data a)
{
	base[++len]=a;
	int pos=len;
	while((pos>>1)&&base[pos]<base[pos>>1])
	{
		swap(base[pos],base[pos>>1]);
		pos>>=1;
	}
	return ;
}
void pop()
{
	swap(base[1],base[len--]);
	int pos=1,nxt;
	while(true)
	{
		nxt=pos;
		if(base[pos<<1]<base[nxt]&&(pos<<1)<=len)
			nxt=pos<<1;
		if(base[pos<<1|1]<base[nxt]&&(pos<<1|1)<=len)
			nxt=pos<<1|1;
		if(pos==nxt)	break;
		swap(base[pos],base[nxt]);
		pos=nxt;
	}
	return ;
}
void add(int a,int b)
{
	line[++tail].p=b;
	line[tail].nxt=head[a];
	head[a]=tail;
}
queue<int>Q;
void danger()
{
	while(!Q.empty())
	{
		int pas=Q.front();Q.pop();
		for(int i=head[pas];i;i=line[i].nxt)
			if(!Dan[line[i].p]&&Dan[pas]<s)
			{
				Dan[line[i].p]=Dan[pas]+1;
				Q.push(line[i].p);
			}
	}
	for(int i=1;i<=k;i++)	Dan[zombie[i]]=-1;
}
int main()
{
	memset(dis,127,sizeof(dis));
	scanf("%d%d%d%d%d%d",&n,&m,&k,&s,&p,&q);
	for(int i=1;i<=k;i++)
	{
		scanf("%d",&zombie[i]);	
		Q.push(zombie[i]);
	}
	int a,b;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a,&b);
		add(a,b);add(b,a);
	}
	danger();
	Data pas,nxt;pas.p=1;pas.dis=0;
	push(pas);
	while(len)
	{
		pas=top();
		while(get[pas.p]){ pop();pas=top(); }
		get[pas.p]=true;dis[pas.p]=pas.dis;
		if(pas.p==n)	break;
		for(int i=head[pas.p];i;i=line[i].nxt)
		{
			int v=line[i].p;
			long long dist=p;
			if(Dan[v]==-1)		continue;
			if(Dan[v])	dist=q;
			if(v==n)	dist=0;
			if(dis[pas.p]+dist<dis[v])
			{
				nxt.p=v;
				nxt.dis=dis[v]=dis[pas.p]+dist;
				push(nxt);
			}
		}
	}
	printf("%lld",dis[n]);
}
原文地址:https://www.cnblogs.com/Lance1ot/p/9648908.html