首页 > 代码库 > [luoguP2622] 关灯问题II(状压最短路)

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

传送门

 

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

所以写一手状压spfa

 

#include <queue>#include <cstdio>#include <cstring>#include <iostream>#define N 11#define M 101int 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(状压最短路)