题目描述

密室中有 N 个房间,初始时,小 X 在 1 号房间,而出口在 N 号房间。

密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会 单向地

创造一条从房间 X 到房间 Y 的通道。另外,想要通过某个传送门,就必须具备一

些种类的钥匙。幸运的是,钥匙在打开传送门的封印后,并不会消失。

然而,通过密室的传送门需要耗费大量的时间,因此,小 X 希望通过尽可能

少的传送门到达出口,你能告诉小 X 这个数值吗?

另外,小 X 有可能不能逃出这个密室,如果是这样,请输出“No Solution”。

输入输出格式

输入格式:

从文件 room.in 中读取数据。

第一行三个整数 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 种钥匙。

输出格式:

输出一行一个“No Solution”,或一个整数,表示最少通过的传送门数。

输入输出样例

输入样例#1:

3 3 2
1 0
0 1
0 0
1 3 1 1
1 2 1 0
2 3 1 1
输出样例#1:

2

说明

n <= 5000 m <= 6000 k <= 10

分析:本质上还是最短路,只是多了钥匙的限制,那么就要在状态的记录上和vis数组上花功夫,毕竟,我们总不能开一个10维数组来一个一个判断吧.

观察发现k非常小,而且有0/1性质:我们可以选或不选,而且只有这两种选择,那么可以很自然的想到状态压缩,利用二进制来维护信息.这个时候,检验能不能通过传送门i,则当前的钥匙状态sta & i 是不是等于i,到达一个房间后我们sta |= room[i]就好了,room[i]表示第i个房间的钥匙的状态数.

不过我打的是spfa,不是正确的解法,观察发现边权为1,这就是bfs!

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue> using namespace std; const int inf = 0x7ffffff; int n, m, k,room[],head[],to[],nextt[],tot = ,w[],d[],vis[][]; struct node
{
int x,sta;
}; void add(int x, int y, int z)
{
w[tot] = z;
to[tot] = y;
nextt[tot] = head[x];
head[x] = tot++;
} void spfa()
{
queue <node> q;
for (int i = ; i <= n; i++)
d[i] = inf;
d[] = ;
node temp;
temp.x = ;
temp.sta = room[];
vis[][room[]] = ;
q.push(temp);
while (!q.empty())
{
node u = q.front();
q.pop();
int x = u.x, sta = u.sta;
vis[x][sta] = ;
for (int i = head[x]; i; i = nextt[i])
{
if ((w[i] & sta) == w[i])
{
int v = to[i];
if (d[v] > d[x] + )
{
d[v] = d[x] + ;
int nsta = (sta | room[v]);
if (!vis[v][nsta])
{
vis[v][nsta] = ;
node t;
t.x = v;
t.sta = nsta;
q.push(t);
}
}
}
}
}
} int main()
{
scanf("%d%d%d", &n, &m, &k);
for (int i = ; i <= n; i++)
{
int sta = ;
for (int j = ; j < k; j++)
{
int t;
scanf("%d", &t);
sta |= (t << j);
}
room[i] = sta;
}
for (int i = ; i <= m; i++)
{
int x, y, sta = ;
scanf("%d%d", &x, &y);
for (int j = ; j < k; j++)
{
int t;
scanf("%d", &t);
sta |= (t << j);
}
add(x, y, sta);
}
spfa();
if (d[n] == inf)
printf("No Solution");
else
printf("%d\n", d[n]); return ;
}

常州模拟赛d2t2 小X的密室的更多相关文章

  1. 常州模拟赛d2t3 小X的佛光

    平日里最喜欢做的事就是蒸发学水.[题目描述]小 X 所在的城市 X 城是一个含有 N 个节点的无向图,同时,由于 X 国是一个发展中国家,为了节约城市建设的经费,X 国首相在建造 X 城时只建造 N ...

  2. 常州模拟赛d2t1 小X的质数

    题目背景 小 X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的 情感.小 X 认为,质数是一切自然数起源的地方. 题目描述 在小 X 的认知里,质数是除了本身和 1 以外,没有其他因 ...

  3. 2014.7.7 模拟赛【小K的农场】

    3.小K的农场(farm.pas/cpp/c) [题目描述] 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三 ...

  4. 计蒜客模拟赛D2T2 蒜头君的排序:区间逆序对(移动端点) + 树状数组

    题目链接:https://nanti.jisuanke.com/t/16443 题意: 给你一个由1~n构成的正整数序列,有m组询问,每组询问要求输出[l , r]区间内的逆序对个数. 数据范围: 对 ...

  5. 【20170920校内模拟赛】小Z爱学习

    所有题目开启-O2优化,开大栈空间,评测机效率为4亿左右. T1 小 Z 学数学(math) Description ​ 要说小 Z 最不擅长的学科,那一定就是数学了.这不,他最近正在学习加法运算.老 ...

  6. 常州模拟赛d4t3 字符串划分

    题目描述 给你一串由小写字母组成的字符串,希望你把它划分成一些小段,使得每一小段字符串中的字母 都不相同,并且希望分的段数尽量少. 然后,把这些小段按字典序排序后输出,中间由一个空格分隔. 例如:字符 ...

  7. 常州模拟赛d4t1 立方体

    题目描述 立方体有 6 个面,每个面上有一只奶牛,每只奶牛都有一些干草.为了训练奶牛的合作精神,它 们在玩一个游戏,每轮:所有奶牛将自己的干草分成 4 等份,分给相邻的 4 个面上的奶牛. 游戏开始, ...

  8. 常州模拟赛d3t3 两只怪物心心相印

    题目背景 从前我是一位无名的旅人,旅途中我得到了某样东西:贤者之石.我因此得到悠久的时光和漂泊的生命.1897年冬天,我一时兴起舍弃了旅人的生活. 贤者之石创造出来的,是货真价实的黄金.我的名声传遍了 ...

  9. 常州模拟赛d3t1 神在夏至祭降下了神谕

    题目描述 我们村子在过去的400年中,断绝与下界的接触,过着自给自足的生活. 夏至祭是一场迎接祖灵于夏季归来,同时祈求丰收的庆典. 村里的男人会在广场上演出夏之军和冬之军的战争.夏之军会打倒冬之军的大 ...

随机推荐

  1. Azure 项目构建 – 托管静态网站

    本课程主要介绍了如何在 Azure 平台上快速构建和部署基于 Azure Web 应用的静态托管网站, 实践讲解如何使用 Azure 门户创建 Web 应用, 部署静态网站源代码,设置自定义域名等. ...

  2. MySQL存储过程简介和引擎说明

  3. SWTError: No more handles [gtk_init_check() failed] running platform tests (on Linux)

    http://www.lemmster.de/2013-12-19-swterror-no-more-handles-gtk_init_check-failed-running-platform-te ...

  4. Java-NestedClass(Interface).

    内部类(Nested Class) 内部类:即在一个类中还包含着另外一个类,一般是作为匿名类或者是使用数据隐藏时使用的.例子: //内部类 class Out{ private int age = 1 ...

  5. 关于java中实现在oracle数据库中实现对中文首字母进行排序的解决方案

    首先介绍Oracle 9i新增加的一个系统自带的排序函数 1.按首字母排序 在oracle9i中新增了按照拼音.部首.笔画排序功能.设置NLS_SORT值     SCHINESE_RADICAL_M ...

  6. WPF中的TextBlock处理长字符串

    Xaml: <StackPanel> <TextBlock Margin="10" Foreground="Red"> This is ...

  7. C#背景图片自适应

    1.选中窗体修改属性 2.在load添加代码 private void Form1_Load(object sender, EventArgs e) { this.BackgroundImageLay ...

  8. python基本排序算法(一)

    一.冒泡排序 这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”. 冒泡排序算法的原理如下: 比 ...

  9. 控制器生命周期方法(LifeCycle)

    1.init方法: 在init方法中实例化必要的对象(遵从LazyLoad思想) ‍init方法中初始化ViewController本身   2.loadView方法:    当view需要被展示而它 ...

  10. 分享一个C++与Python开发的中小型通用游戏服务端框架(跨平台,开源,适合MMORPG游戏)

    在开发一款游戏项目时,在立项时我们往往会考虑或者纠结很多,比如: 1,对于开发来说:服务端和客户端应该选择什么语言?用什么协议通信才更效率?协议后期如何维护?Socket是用长连接还是短连接?TCP还 ...