5459. 【NOIP2017提高A组冲刺11.7】密室
(File IO): input:room.in output:room.out
Time Limits: 1000 ms Memory Limits: 524288 KB Detailed Limits
Goto ProblemSet做法: 将K状态压缩后直接bfs即可
代码如下:
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <queue> #include <algorithm> #define N 5007 using namespace std; int n, m, k, pre[N], dis[N][1300], ls[N]; int mi[30], tot; struct edge { int to, next, pre; }e[N * 2]; int list[N * 3330][2]; void add(int x, int y, int z) { e[++tot].to = y; e[tot].next = ls[x]; e[tot].pre = z; ls[x] = tot; } void init() { scanf("%d%d%d", &n, &m, &k); for (int i = 1; i <= n; i++) { int x; pre[i] = 0; for (int j = 1; j <= k; j++) { scanf("%d", &x); pre[i] += x * mi[j]; } } for (int i = 1; i <= m; i++) { int x, y, z; scanf("%d%d", &x, &y); int p = 0; for (int j = 1; j <= k; j++) scanf("%d", &z), p += mi[j] * z; add(x, y, p); } } void pre_work() { mi[1] = 1; for (int i = 2; i <= 12; i++) mi[i] = mi[i - 1] * 2; } void work() { memset(dis, 0x7f7f7f7f, sizeof(dis)); dis[1][pre[1]] = 0; list[1][0] = 1; list[1][1] = pre[1]; int head = 0, tail = 1; while (head < tail) { head++; int now = list[head][0]; int p = list[head][1]; for (int i = ls[now]; i; i = e[i].next) { if ((p | e[i].pre) != p) continue; int net = p | pre[e[i].to]; if (dis[e[i].to][net] == 0x7f7f7f7f) { dis[e[i].to][net] = dis[now][p] + 1; list[++tail][0] = e[i].to; list[tail][1] = net; } } } int ans = 0x7f7f7f7f; for (int i = 0; i <= mi[k + 1] - 1; i++) ans = min(ans, dis[n][i]); if (ans != 0x7f7f7f7f) printf("%d", ans); else printf("No Solution"); } int main() { //freopen("room.in", "r", stdin); //freopen("room.out", "w", stdout); pre_work(); init(); work(); }