Description
小X 正困在一个密室里,他希望尽快逃出密室。
密室中有N 个房间,初始时,小X 在1 号房间,而出口在N 号房间。
密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会单向地创造一条从房间X 到房间Y 的通道。另外,想要通过某个传送门,就必须具备一些种类的钥匙(每种钥匙都要有才能通过)。幸运的是,钥匙在打开传送门的封印后,并不会消失。
然而,通过密室的传送门需要耗费大量的时间,因此,小X 希望通过尽可能少的传送门到达出口,你能告诉小X 这个数值吗?
另外,小X 有可能不能逃出这个密室,如果是这样,请输出"No Solution"。
密室中有N 个房间,初始时,小X 在1 号房间,而出口在N 号房间。
密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会单向地创造一条从房间X 到房间Y 的通道。另外,想要通过某个传送门,就必须具备一些种类的钥匙(每种钥匙都要有才能通过)。幸运的是,钥匙在打开传送门的封印后,并不会消失。
然而,通过密室的传送门需要耗费大量的时间,因此,小X 希望通过尽可能少的传送门到达出口,你能告诉小X 这个数值吗?
另外,小X 有可能不能逃出这个密室,如果是这样,请输出"No Solution"。
Input
第一行三个整数N,M,K,分别表示房间的数量、传送门的数量以及钥匙的种类数。
接下来N 行,每行K 个0 或1,若第i 个数为1,则表示该房间内有第i 种钥匙,若第i 个数为0,则表示该房间内没有第i 种钥匙。
接下来M 行,每行先读入两个整数X,Y,表示该传送门是建立在X 号房间,通向Y 号房间的,再读入K 个0 或1,若第i 个数为1,则表示通过该传送门需要i 种钥匙,若第i 个数为0,则表示通过该传送门不需要第i 种钥匙。
接下来N 行,每行K 个0 或1,若第i 个数为1,则表示该房间内有第i 种钥匙,若第i 个数为0,则表示该房间内没有第i 种钥匙。
接下来M 行,每行先读入两个整数X,Y,表示该传送门是建立在X 号房间,通向Y 号房间的,再读入K 个0 或1,若第i 个数为1,则表示通过该传送门需要i 种钥匙,若第i 个数为0,则表示通过该传送门不需要第i 种钥匙。
Output
输出一行一个“No Solution”,或一个整数,表示最少通过的传送门数。
Sample Input
3 3 2 1 0 0 1 0 0 1 3 1 1 1 2 1 0 2 3 1 1
Sample Output
2
Data Constraint


话说这题很眼熟啊...
直接状压一发,然后跑一个bfs。
其实是码农题, 此题一A没有调试真的是特别爽。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; inline int read() { int res=0;char c=getchar();bool f=0; while(!isdigit(c)) {if(c=='-')f=1;c=getchar();} while(isdigit(c))res=(res<<3)+(res<<1)+(c^48),c=getchar(); return f?-res:res; } int n, m, k; struct edge{ int nxt, to, sit; }ed[6006]; int head[5005], cnt; inline void add(int x, int y, int z) { ed[++cnt] = (edge){head[x], y, z, }; head[x] = cnt; } int w[5005]; struct date { int x, sit; }; int dis[1<<11][5005]; int main() { freopen("room.in", "r", stdin); freopen("room.out", "w", stdout); n = read(), m = read(), k = read(); for (int i = 1; i <= n; i ++) { int x = 0; for (int j = 1 ; j <= k ; j ++) { x <<= 1; x |= read(); } w[i] = x; } for (int i = 1 ; i <= m ; i ++) { int x = read(), y = read(); int re = 0; for (int j = 1 ; j <= k ; j ++) { re <<= 1; re |= read(); } add(x, y, re); } queue <date> q; memset(dis, -1, sizeof dis); q.push((date){1, w[1]}); dis[w[1]][1] = 0; while(!q.empty()) { int x = q.front().x, so = q.front().sit; q.pop(); for (int i = head[x] ; i ; i = ed[i].nxt) { int to = ed[i].to; if ((so & ed[i].sit) == ed[i].sit and dis[so|w[to]][to] == -1) { dis[so|w[to]][to] = dis[so][x] + 1; q.push((date){to, so | w[to]}); } } } int ans = 1e9; for (int i = 0 ; i <= (1 << k) - 1 ; i ++) if (dis[i][n] != -1)ans = min(ans, dis[i][n]); if (ans == 1e9) return puts("No Solution"), 0; printf("%d\n", ans); return 0; }