[luoguP2622] 关灯问题II(状压最短路)

Posted 蒟蒻zht的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luoguP2622] 关灯问题II(状压最短路)相关的知识,希望对你有一定的参考价值。

传送门

 

本以为是状压DP,但是有后效性。

所以写一手状压spfa

 

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 11
#define M 101

int n, m;
int a[M][N], dis[1 << N];
std::queue <int> q;
bool vis[1 << N];

inline int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;
	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;
	return x * f;
}

inline void spfa()
{
	int i, j, u, v;
	memset(dis, 127 / 3, sizeof(dis));
	dis[0] = 0;
	q.push(0);
	while(!q.empty())
	{
		u = q.front();
		vis[u] = 0;
		q.pop();
		for(i = 1; i <= m; i++)
		{
			v = u;
			for(j = 1; j <= n; j++)
			{
				if(a[i][j] == 1 && !(v & (1 << j - 1))) v |= 1 << j - 1;
				if(a[i][j] == -1 && (v & (1 << j - 1))) v ^= 1 << j - 1;
			}
			if(dis[v] > dis[u] + 1)
			{
				dis[v] = dis[u] + 1;
				if(!vis[v])
				{
					q.push(v);
					vis[v] = 1;
				}
			}
		}	
	}
}

int main()
{
	int i, j;
	n = read();
	m = read();
	for(i = 1; i <= m; i++)
		for(j = 1; j <= n; j++)
			a[i][j] = read();
	spfa();
	printf("%d\n", dis[(1 << n) - 1] <= 1e8 ? dis[(1 << n) - 1] : -1);
	return 0;
}

  

以上是关于[luoguP2622] 关灯问题II(状压最短路)的主要内容,如果未能解决你的问题,请参考以下文章

[luoguP2761] 软件补丁问题(状压最短路)

p2622 关灯问题II

P2622 关灯问题II(状态压缩+BFS)

luogu p2622关灯问题II

P2761 软件补丁问题 状压最短路

[Luogu2622]关灯问题$||$(状压$DP$)