HDU 3440 House Man (restricción diferencial)

Pregunta: Hay N casas en línea recta. Cada casa tiene una altura diferente. Superman puede mover estas casas de izquierda a derecha, pero no puede cambiar la posición relativa entre las casas. Superman quiere saltar de la casa más corta a una casa un poco más alta que él, y cada vez que salta una casa más alta que la casa actual, tiene que saltar N-1 veces. Entonces, al final, Superman definitivamente saltará a la casa más alta. Ahora da la distancia D más larga que Superman puede saltar a la vez. Cómo organizar estas casas para que Superman pueda saltar a través de todas las casas hasta la casa más alta, y hacerla la más corta La distancia entre la casa y la casa más alta es la más lejana y la salida es la más lejana.

Solución del problema: restricción de diferencia
Encuentra la distancia más larga y recorre el camino más corto. Usamos d [i] d [i]d [ i ] representa la distancia desde el punto de partida.

Dado que el orden inherente de la casa no cambia, se puede obtener la ecuación de restricción:
d [i - 1] - d [i] <= - 1 d [i-1] -d [i] <= - 1d [ i-1 ]-d [ i ]<=- 1

Luego considere el orden de salto, debido a que la distancia entre las dos casas no puede exceder D, podemos establecer restricciones basadas en el tamaño de la identificación después de la clasificación.

Al mismo tiempo, también se debe considerar el tamaño de la identificación del punto de inicio y el punto final. Debido a que el resultado final es positivo, la identificación del punto de partida debe ser menor que el punto final, independientemente de si salta de menor a mayor o de mayor a menor.

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
#define pii pair<int, int>
using namespace std;
const int maxn = 1e3 + 5;
int t, n, D;
struct node1 {
    
    
	int h, id;
	bool operator<(const node1 x)const {
    
    
		return h < x.h;
	}
}h[maxn];
struct node {
    
    
	int v, nxt, w;
}edge[maxn << 2];
int vis[maxn], d[maxn], head[maxn], mark[maxn], k, s;
void add(int u, int v, int w) {
    
    
	edge[++k].nxt = head[u];
	edge[k].v = v;
	edge[k].w = w;
	head[u] = k;
}
bool spfa() {
    
    
	for (int i = 1; i <= n; i++) {
    
    
		vis[i] = mark[i] = 0;
		d[i] = 0x3f3f3f3f;
	}
	queue<int>q;
	q.push(s);
	mark[s] = vis[s] = 1;
	d[s] = 0;
	while (!q.empty()) {
    
    
		int u = q.front(); q.pop();
		vis[u] = 0;
		for (int i = head[u]; i; i = edge[i].nxt) {
    
    
			int v = edge[i].v, w = edge[i].w;
			if (d[v] > d[u] + w) {
    
    
				d[v] = d[u] + w;
				if (vis[v]) continue;
				vis[v] = 1;
				if(++mark[v] > n) return false;  //负环 n+1以上才有负环
				q.push(v);
			}
		}
	}
	return true;
}

int main() {
    
    
	int cas = 0;
	scanf("%d", &t);
	while (t--) {
    
    
		k = 0;
		memset(head, 0, sizeof(head));
		scanf("%d%d", &n, &D);
		for (int i = 1; i <= n; i++) {
    
    
			scanf("%d", &h[i].h);
			h[i].id = i;
			if (i != 1) add(i, i - 1, -1);
		}
		sort(h + 1, h + n + 1);
		for (int i = 2; i <= n; i++) {
    
    
			if (h[i].id > h[i - 1].id) add(h[i - 1].id, h[i].id, D);
			else add(h[i].id, h[i - 1].id, D);
		}
		s = min(h[1].id, h[n].id);
		if (spfa()) printf("Case %d: %d\n", ++cas, d[max(h[1].id, h[n].id)]);
		else printf("Case %d: %d\n", ++cas, -1);
	}
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_43680965/article/details/108757913
Recomendado
Clasificación