题目描述

密室中有 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. C#操作Txt(追加模式)

    /// <summary> /// 输出指定信息到文本文件 /// </summary> /// <param name="msg">输出信息& ...

  2. MVC简单登陆验证

    配置文件: <system.web> <authentication mode="Forms"> <!-- 如果验证失败就返回URL的指定界面,设置c ...

  3. JS中的delete操作符

    首先,delete删除成功返回true,失败返回false. js代码: function wxCount ($element) { this.init($element); } wxCount.pr ...

  4. 理解Vue

    Vue.js是JavaScript MVVM(Model-View-ViewModel)库,十分简洁,Vue核心只关注视图层,相对AngularJS提供更加简洁.易于理解的API.Vue尽可能通过简单 ...

  5. 讲课笔记1——meta标签、表格标签

    图片属性:src(source): 图片的来源(路径),可以放置本地图片,也可以放网上的图片的url地址 [相对路径:        ./:当前目录            ../:跳出当前目录,到上一 ...

  6. Codeforces Round #272 (Div. 2)-A. Dreamoon and Stairs

    http://codeforces.com/contest/476/problem/A A. Dreamoon and Stairs time limit per test 1 second memo ...

  7. 005 String s = "Hello";s = s + " world!";执行这两行代码执行后,原始的 String 对象中的内容到底变了没有?

    原始的String对象中的内容没有改变成“Hello world”. 1.原因 因为在Java中String类被设计成不可改变的类,所以String类的所有对象都是不可变的.第一句代码中,s(存储在栈 ...

  8. ASIHTTPRequest简单学习

    ASIHTTPRequest框架是优秀的第三方Objective-C的HTTP框架,支持Mac OS X和iOS下的HTTP开发. 一.ASIHTTPRequest框架的安装和配置 (1)首先要在项目 ...

  9. HDU-2544-最短路(floyd)

    板子题,实验一下floyd. #include <cstdio> #include <algorithm> #include <cstring> using nam ...

  10. perl学习之I/O基础

    1.从标准输入进行输入<STDIN> 2.从钻石操作符进行输入<> 3.参数调用@ARGV 4.向标准输出进行输出 5.用printf进行格式化输出 1.<STDIN&g ...