P1173 [NOI2016] Cuadrícula

Proveedor de temas Luogu

Dificultad NOI/NOI+/CTSC

Puntuación de historia 100

Tema Descripción

King Flea y King Cricket están jugando.

Están dispuestos en una cuadrícula de n filas ym columnas. Entre las cuadrículas cc (0 ≤ c ≤ n⋅m), cada cuadrícula tiene un grillo y, en las cuadrículas restantes, cada cuadrícula tiene una pulga.

Decimos que dos pulgas que ocupan una cuadrícula con un borde común son adyacentes.

Decimos que dos pulgas están conectadas si y sólo si las dos pulgas son adyacentes, o hay otra pulga que está conectada a ambas pulgas.

Ahora, el rey del grillo espera que algunas (cero, una o más) pulgas sean reemplazadas por grillos, de modo que después de eso queden al menos dos pulgas desconectadas. [imagen]

Por ejemplo: la Figura 1 muestra un caso en el que n=4, m=4, c=2.

En este caso, King Cricket puede lograr su deseo reemplazando las dos pulgas de la segunda fila, segunda columna y de la tercera fila, tercera columna con grillos, como se muestra en la figura de la derecha. Además, no existe una solución mejor, pero puede haber otras soluciones para reemplazar las dos pulgas.

Primero debes juzgar si se puede cumplir el deseo del rey del cricket. Si se puede lograr, también es necesario minimizar la cantidad de pulgas que se reemplazan.

formato de entrada

Cada archivo de entrada contiene múltiples conjuntos de datos.

La primera línea del archivo de entrada tiene solo un número entero T, que indica el número de grupos de datos.

A continuación, ingrese conjuntos de datos TT en secuencia, la primera línea de cada conjunto de datos contiene tres números enteros n, m, c.

Las siguientes c líneas, cada línea contiene dos números enteros x, y significa que la cuadrícula en la fila x y la columna y está ocupada por un grillo. En cada conjunto de datos, el mismo grillo no se describirá varias veces.

formato de salida

Para cada conjunto de datos, genere una línea de respuestas por turno.

Si el deseo del rey del cricket no se puede cumplir en este conjunto de datos, genere -1. De lo contrario, genere la cantidad mínima de pulgas reemplazadas.

Muestras de entrada y salida

entrada#1

4
4 4 2
1 1
4 4
2 3 1
1 2
2 2 2
1 1
2 2
1 1 0

Salida #1

2
1
0
-1

 

Instrucciones/Consejos

explicación de muestra

El primer conjunto de datos es el ejemplo de la descripción del problema.

Para el segundo conjunto de datos, una pulga en la segunda fila y la segunda columna se puede reemplazar con un grillo, de modo que hay dos pulgas que no están conectadas y no hay mejor solución.

Para el tercer conjunto de datos, inicialmente se desconectan dos pulgas, por lo que no es necesario reemplazarlas.

Para el cuarto conjunto de datos, dado que solo hay una pulga como máximo, no se pueden desconectar dos pulgas sin importar cómo se reemplacen.

rango de datos

Para todos los puntos de prueba, se garantiza que 1≤T≤20. Registramos ∑c como la suma de todos c de sus T conjuntos de datos de entrada en un determinado punto de prueba. Para todos los puntos de prueba, Σc≤105.

Para todos los datos, satisfaga 1≤n, m≤10^9, 0≤c≤n×m, 1≤x≤n, 1≤y≤m.

El rango de datos detallado de cada punto de prueba se muestra en la siguiente tabla. Los n, myc en la tabla son todos para un solo dato de entrada (no un punto de prueba), es decir, los T grupos de datos bajo el mismo punto de prueba cumplen todos las condiciones de restricción; y ∑c es para un solo punto de prueba hablado. Para facilitar la lectura, la columna "Punto de prueba" se ha colocado en el medio de la tabla en lugar de a la izquierda.

 Ideas para resolver problemas:

 Los que tienen grillos se consideran puntos negros y los que tienen pulgas se consideran puntos blancos.

Obviamente la respuesta sólo puede ser ninguna solución o 0,1,2.

  • Si el gráfico compuesto por las cuatro celdas blancas conectadas no está conectado, la respuesta es 0.

  • En caso contrario, si la gráfica tiene puntos de corte, la respuesta es 1

  • De lo contrario, si la gráfica no tiene más de dos puntos, no hay solución.

  • de lo contrario 2

Los primeros tres casos son obvios y el último caso pueden ser subgráficos con 33 puntos y más de 33 puntos respectivamente.

Entonces, construir directamente un mapa y ejecutar tarjan puede ser O (nm).

Sin embargo, este gráfico tiene muchos puntos pero pocas vacantes. Considere reducirlo a un gráfico con O (c) puntos y lados para que la respuesta permanezca sin cambios después de reducirlo.

Considere conservar solo los siguientes puntos blancos:

  • La diferencia de las coordenadas x,yx,y de al menos una de las cuatro esquinas de la cuadrícula \leq2≤2

  • conectado con cierto punto negro ocho

  • En la parte superior o inferior de la cuadrícula con al menos un punto negro en la columna

  • En el lado izquierdo o derecho de la cuadrícula con al menos un punto negro en la fila

Luego, para todos los puntos blancos restantes, si los dos puntos blancos están en la misma fila o columna y no hay otros puntos en el medio (incluidos los puntos negros y los puntos blancos restantes), conecte un lado.

Tenga en cuenta que no solo se construyen cuatro bordes conectados.

Por ejemplo, la cuadrícula azul es el punto reservado.

Luego descubrí que la respuesta de esta imagen es la misma que la respuesta de la imagen original en la mayoría de los casos, pero al juzgar -1, es necesario juzgar especialmente si hay dos puntos en la imagen, pero los dos puntos tienen bordes. pero no son cuatro conexos, en este caso, en realidad habrá al menos tres puntos y la respuesta es 1, o puedes juzgar n = 1, m = 1.

No sé si es correcto, y si es correcto, ¿cómo puedo probarlo? De todos modos, después de todos los datos de pirateo de uoj , bienvenido a continuar pirateando.

Y considerando que cada punto negro solo contribuirá con hasta 8 puntos a su alrededor y 4 puntos a su lado, un total de 12 puntos, es decir, un total de O(c) puntos.

Entonces el cuello de botella de la complejidad radica en la construcción del mapa, la complejidad Θ(clogc)

Código estándar:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
const int P=1000117;
const int N=100050;
char rB[1<<21],*rS,*rT;
inline char gc(){return rS==rT&&(rT=(rS=rB)+fread(rB,1,1<<21,stdin),rS==rT)?EOF:*rS++;}
inline int rd(){
    char c=gc();
    while(c<48||c>57)c=gc();
    int x=c&15;
    for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15);
    return x;
}
int x[N],y[N],G[N*24],to[N*192],nxt[N*192],sz,cnt,pre[N*24],dfsc,n,m,c,tmpx[N*24],tmpy[N*24],ctmp;
bool isok[N*24],iscut[N*24];
struct node{
	int x,y;
	node(){}
	node(int x,int y):x(x),y(y){}
};
queue<node> Q,q;
struct Hash{  //用hash实现map
	int h[P],vx[N*25],vy[N*25],p[N*25],nxt[N*25],sz;
	inline void clear(){
		memset(h,0,sizeof(h));sz=0;
	}
	inline void ins(int x,int y,int id){
		int pos=((ll)(x-1)*n+y-1)%P;
		vx[++sz]=x;vy[sz]=y;p[sz]=id;nxt[sz]=h[pos];h[pos]=sz;
	}
	inline int ask(int x,int y){
		for(int k=h[((ll)(x-1)*n+y-1)%P];k;k=nxt[k])if(vx[k]==x&&vy[k]==y)return p[k];
		return 0;
	}
}h,col,tem;
inline int Abs(int x){return x<0?-x:x;}
inline int Max(int a,int b){return a>b?a:b;}
inline void add(int u,int v){
	to[++sz]=v;nxt[sz]=G[u];G[u]=sz;
	to[++sz]=u;nxt[sz]=G[v];G[v]=sz;
}
inline bool check(){
	int i,j,k,tx,ty;
	for(i=1;i<=n;++i)
		for(j=1;j<=m;++j)if(!h.ask(i,j)){
			for(k=0;k<4;++k)if((tx=i+dx[k])&&tx<=n&&(ty=j+dy[k])&&ty<=m&&!h.ask(tx,ty))return 1;
			return 0;
		}
}
inline void bfs(int sx,int sy,int cl){  //第一次floodfill
	int i,u,v,tx,ty;
	q.push(node(sx,sy));col.ins(sx,sy,cl);
	while(!q.empty()){
		u=q.front().x;v=q.front().y;q.pop();
		for(i=0;i<4;++i)if((tx=u+dx[i])&&tx<=n&&(ty=v+dy[i])&&ty<=m&&h.ask(tx,ty)>0&&!col.ask(tx,ty)){
			col.ins(tx,ty,cl);  //用col来记录所属联通块编号(也成为颜色)
			q.push(node(tx,ty));
		}
	}
}
inline bool bfs2(int sx,int sy){
	int i,u,v,x,y,t;
	q.push(node(sx,sy));tem.ins(sx,sy,-1);
	while(!q.empty()){
		u=q.front().x;v=q.front().y;q.pop();
		for(x=Max(1,u-1);x<=n&&x<=u+1;++x)
			for(y=Max(1,v-1);y<=m&&y<=v+1;++y)if((t=h.ask(x,y))&&!tem.ask(x,y))if(t==-1){
				tem.ins(x,y,-1);  //用tem来防止对障碍结点重复访问
//对跳蚤结点的重复访问最多总共c*8个,不会影响复杂度
				q.push(node(x,y));
			}else{tmpx[++ctmp]=x;tmpy[ctmp]=y;}
	}
	if(ctmp==-1)return 1;
	for(i=1,t=col.ask(tmpx[0],tmpy[0]);i<=ctmp;++i)if(col.ask(tmpx[i],tmpy[i])!=t)return 0;
	return 1;
}
inline bool ncon(){  //判断是否不连通
	int i,u,v,ccl=0;
	col.clear();
	while(!Q.empty()){
		u=Q.front().x;v=Q.front().y;Q.pop();
		if(col.ask(u,v))continue;
		bfs(u,v,++ccl);
	}
	tem.clear();
	for(i=0;i<c;++i)if(!tem.ask(x[i],y[i])){
		ctmp=-1;
		if(!bfs2(x[i],y[i]))return 1;
	}
	return 0;
}
int dfs(int u,int fa){  //dfs求割顶
	int i,v,lowu=pre[u]=++dfsc,lowv,chd=0;
	for(i=G[u];i;i=nxt[i])if((v=to[i])!=fa)if(!pre[v]){
		++chd;
		if((lowv=dfs(v,u))>=pre[u])iscut[u]=1;
		if(lowv<lowu)lowu=lowv;
	}else if(pre[v]<lowu)lowu=pre[v];
	if(!fa&&chd==1)iscut[u]=0;
	return lowu;
}
int main(){
	int T=rd(),i,j,k,l,t,tt,tx,ty;
	bool ok;
	while(T--){
		n=rd();m=rd();c=rd();
		h.clear();
		for(i=0;i<c;++i){
			x[i]=rd();y[i]=rd();
			h.ins(x[i],y[i],-1);
		}
		if((ll)n*m-c<2ll){
			puts("-1");
			continue;
		}
		if((ll)n*m-c==2ll){
			puts(check()?"-1":"0");
			continue;
		}
		memset(G,0,sizeof(G));ok=sz=cnt=dfsc=0;
		memset(pre,0,sizeof(pre));
		memset(iscut,0,sizeof(iscut));
		memset(isok,0,sizeof(isok));
        //建图
		for(i=0;i<c;++i)
			for(j=Max(1,x[i]-2);j<=x[i]+2&&j<=n;++j)
				for(k=Max(1,y[i]-2);k<=y[i]+2&&k<=m;++k)if(!(t=h.ask(j,k))){
					h.ins(j,k,++cnt);Q.push(node(j,k));
					isok[cnt]=Max(Abs(j-x[i]),Abs(k-y[i]))<=1;
					for(l=0;l<4;++l)if((tx=j+dx[l])&&tx<=n&&(ty=k+dy[l])&&ty<=m&&(tt=h.ask(tx,ty))>0)add(cnt,tt);
				}else if(t>0&&Max(Abs(j-x[i]),Abs(k-y[i]))<=1)isok[t]=1;
		if(ncon()){
			puts("0");
			continue;
		}
		if(n==1||m==1){  //一行或一列可以特判
			puts("1");
			continue;
		}
		for(i=1;i<=cnt;++i){
			if(!pre[i])dfs(i,0);
			if(isok[i]&&iscut[i]){
				puts("1");
				ok=1;break;
			}
		}
		if(!ok)puts("2");
	}
	return 0;
}

A través de imagen:

¡Gracias por ver! 

Supongo que te gusta

Origin blog.csdn.net/asuf1364/article/details/132119859
Recomendado
Clasificación