Problema de repostaje del coche Luogu P4009 (el camino más corto en el mapa jerárquico)

enlace

La pregunta debe satisfacer tres condiciones:
1: Cuando el automóvil pasa por un borde de la cuadrícula, si su coordenada X o la coordenada Y disminuye, se pagará la tarifa B, de lo contrario la tarifa es gratuita.

2: Cuando el automóvil se encuentra con el depósito de aceite durante la conducción, debe llenarse y pagar la tarifa de repostaje A.

3: Puede agregar depósitos de petróleo en los puntos de la cuadrícula cuando sea necesario y pagar el costo adicional del depósito de petróleo C (excluyendo el costo de repostaje A).

4: El automóvil solo puede conducir a lo largo de los bordes de la rejilla y puede conducir K bordes de la rejilla después de llenarse de combustible.

Idea: Esta pregunta está en las preguntas de Luogu Network Stream 24, pero las soluciones son las más breves. El camino más corto para la construcción de mapas. De acuerdo con la estratificación de costos, debido a que el aceite completo solo puede ir k veces, lo dividimos en k + 1 capa, la capa 0 representa el aceite completo y la primera capa representa una unidad de consumo de aceite.

Para la primera condición: conectamos un borde dirigido en esta capa a las cuatro direcciones adyacentes a él en la capa superior. Si las coordenadas xoy disminuyen, el peso del borde es b; de lo contrario, el peso del borde es 0.

Para la segunda condición: debido a que es obligatorio repostar cuando se encuentra un depósito de petróleo, para la primera capa y superior, conecte un borde a la primera capa, y el peso del borde es A. En este momento, también es necesario conectar la capa 0 y la primera capa. Capa, pero no te conectes a otras capas. Esto se debe a que si pasas este punto, el siguiente paso solo puede ser la primera capa, no otras capas.

Para la tercera condición: si este punto no es un depósito de petróleo, cada capa conecta un borde con la primera capa y el peso del borde es a + c, lo que significa que se construye un nuevo depósito de petróleo en este punto.

La cuarta condición: construir un mapa en capas

#include <bits/stdc++.h>
#define ll long long
#define pi pair<int,int>
#define mk make_pair
#define pb push_back
using namespace std;

const int maxn = 1e6+10;
int d[maxn],vis[maxn],n;
vector<pi>G[maxn];

int id(int x,int y,int k)
{
    
    
	return n*n*k + ((x-1)*n) + y;
}
void add(int u,int v,int w)
{
    
    
	G[u].pb(mk(v,w));
}

void dij(int s)
{
    
    
	priority_queue<pi>q;
	memset(d,0x3f,sizeof(d));
	d[s] = 0;
	q.push(mk(0,s));
	while(q.size())
	{
    
    
		int u = q.top().second;
		q.pop();
		if(vis[u])continue;
		vis[u] = 1;
		for(int i=0;i<G[u].size();i++)
		{
    
    
			int v = G[u][i].first;
			int w = G[u][i].second;
			if(d[v] > d[u] + w)
			{
    
    
				d[v] = d[u] + w;
				q.push(mk(-d[v],v));
			}
		}
	}
}
int main()
{
    
    
	int k,a,b,c;
	scanf("%d%d%d%d%d",&n,&k,&a,&b,&c);
	for(int x=1;x<=n;x++)
	for(int y=1;y<=n;y++)
	{
    
    
		int ddd;
		scanf("%d",&ddd);
		if(ddd == 1)
		{
    
    
			for(int i=1;i<=k;i++) {
    
    
				add(id(x,y,i) , id(x,y,0) , a);
			}
			if(x+1 <= n) add(id(x, y, 0), id(x+1, y, 1), 0);
			if(x-1 >= 1) add(id(x, y, 0), id(x-1, y, 1), b);
			if(y+1 <= n) add(id(x, y, 0), id(x, y+1, 1), 0);
			if(y-1 >= 1) add(id(x, y, 0), id(x, y-1, 1), b);
		}
		else
		{
    
    
			for(int i=1;i<=k;i++)
			{
    
    
				add(id(x,y,k), id(x,y,0), a+c);
				if(x+1 <= n) add(id(x, y, i-1), id(x+1, y, i), 0);
				if(x-1 >= 1) add(id(x, y, i-1), id(x-1, y, i), b);
				if(y+1 <= n) add(id(x, y, i-1), id(x, y+1, i), 0);
				if(y-1 >= 1) add(id(x, y, i-1), id(x, y-1, i), b);
			}
		}
	}
	int s = id(1,1,0);
	dij(s);
	int ans = 0x3f3f3f3f;
	for(int i=0;i<=k;i++)ans = min(ans , d[id(n,n,i)]);
	printf("%d\n",ans);
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_44499508/article/details/107207778
Recomendado
Clasificación