Matrícula AcWing4084 (y búsqueda/conjunto de bits para optimizar Floyd)

Enlace temático: matrícula

Idea general

dada una longitud de nnsecuencia de n , iiEl valor de i posiciones esai a_iunyo(garantizado aaa es1 11 ~nnuna permutación de n )

También hay un valor di d_i para cada posicióndyo, Wakahiro pie ∣ yo − j = di ∣ |ij = d_i |yoj=dyo , representa la posicióniii y posiciónjjj se puedecambiarcualquier número de veces

P: ¿Puede la secuencia final satisfacer ai = i a_i = iunyo=yo _

Ideas para resolver problemas

y comprobar (Los datos son demasiado pequeños, se escribió un Floyd durante el juego)

Dado que el número de intercambios entre las dos posiciones es arbitrario , por lo tanto, si xxx y y y se puede intercambiar, yyyyzzz se puede intercambiar, entoncesx , y , zx, y, zx ,y,z aaen tres posicionesLos valores de a son intercambiables.

El análisis anterior se puede generalizar a un conjunto conexo de tamaño finito.

Por lo tanto, solo necesitamos juzgar el ai interno a_i de cada conjunto conexounyoSi el valor es el mismo que el conjunto subíndice iiPuedo ser el mismo.


floyd

establecer MP[ ] MP[]m p [ ] , dondemp [ val ] mp[val]m p [ v a l ] registroval valLa posición de la secuencia original donde se encuentra el elemento de v a l .

Consideramos la naturaleza del problema: si hay ai ≠ i a_i \ne iunyo=yo , indicandoiii la posición debe ser la misma quemp[a[i]]mp[a[i]]mp [ a [ i ] ] se intercambian posiciones, es decir: necesitamos juzgar i , ji, jyo ,Si las dos posiciones de j son alcanzables Es más fácil pensaren el procesamientode la ruta más corta de múltiples fuentes

Teniendo en cuenta que este problema no necesita encontrar la distancia entre dos puntos, solo necesita determinar si es alcanzable , por lo que si se usa Floyd FloydAlgoritmo de F l o y d , la tercera capa del bucle se puede considerar como unconjunto de unión, podemos pasarel conjunto de bitsb i t s e t para optimizar.

Al escribir esta práctica, principalmente siento que esta pregunta es un conjunto de bitsb i t s e tOptimización de F loydFloydLas preguntas introductorias de Floyd son amigables .

código de CA

Y comprobar DSU

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 1E2 + 10;
int a[N], d[N];

/* 并查集模版 */
struct DSU {
    
    
	int p[N];
	int find(int x) {
    
     return x == p[x] ? x : p[x] = find(p[x]); }
	void merge(int a, int b) {
    
    
		a = find(a), b = find(b);
		if (a == b) return;
		p[b] = a;
	}
	void init(int n) {
    
     rep(i, n) p[i] = i; }
}dsu;

vector<int> v1[N], v2[N];
int main()
{
    
    
	int n; cin >> n;
	rep(i, n) scanf("%d", &a[i]);
	rep(i, n) scanf("%d", &d[i]);

	dsu.init(n);

	rep(i, n) {
    
    
		int x = i - d[i], y = i + d[i];
		if (x >= 1) dsu.merge(i, x);
		if (y <= n) dsu.merge(i, y);
	}

	rep(i, n) v1[dsu.find(i)].push_back(a[i]), v2[dsu.find(i)].push_back(i);

	bool flag = 1;
	rep(i, n) {
    
    
		if (i != dsu.find(i)) continue;

		sort(v1[i].begin(), v1[i].end());
		if (v1[i] != v2[i]) flag = 0;
	}

	puts(flag ? "YES" : "NO");

	return 0;
}

Floyd + conjunto de bits

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 1E2 + 10;
int a[N], d[N], mp[N];
bitset<N> can[N];

void fact(int a, int b) {
    
     can[a][b] = can[b][a] = 1; }
int main()
{
    
    
	int n; cin >> n;
	rep(i, n) scanf("%d", &a[i]), mp[a[i]] = i;
	rep(i, n) {
    
    
		scanf("%d", &d[i]);
		if (i - d[i] > 0) fact(i, i - d[i]);
		if (i + d[i] <= n) fact(i, i + d[i]);
		can[i][i] = 1;
	}

	rep(k, n) rep(i, n) {
    
    
        if (can[i][k]) can[i] |= can[k];
    }

	bool flag = 1;
	rep(i, n) flag &= can[i][mp[i]];

	puts(flag ? "YES" : "NO");

	return 0;
}

FIN

Supongo que te gusta

Origin blog.csdn.net/weixin_45799835/article/details/121725943
Recomendado
Clasificación