https://nanti.jisuanke.com/t/17323

小 X 正困在一个密室里,他希望尽快逃出密室。

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

密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会单向地创造一条从房间 X 到房间 Y 的通道。另外,想要通过某个传送门,就必须具备一些种类的钥匙(每种钥匙都要有才能通过)。幸运的是,钥匙在打开传送门的封印后,并不会消失。

然而,通过密室的传送门需要耗费大量的时间,因此,小 X 希望通过尽可能少的传送门到达出口,你能告诉小 X 这个数值吗?

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

输入格式

第一行三个整数 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",或一个整数,表示最少通过的传送门数。

思路:

一道很有意思的搜索题,如果没有钥匙存在的话,那么这道题就变成一道纯粹的搜索题了。

在有钥匙存在的情况下,那么思考用什么来表示钥匙的状态最为方便。。。那显然是二进制了,每一次钥匙状态的判断可以用与运算解决,钥匙的传递可以用或运算解决,非常方便而且复杂度极低。

具体看代码以及最后一组测试点没有过(大雾

代码:

 #include <stdio.h>
 #include <string.h>
 #include <queue>
 #include <vector>
 using namespace std;

 ];
 ];
 ];

 int n,m,k;

 struct edge
 {
     int from,to;
     int cost;
 };

 vector<edge> edges;
 vector<];

 void adde(int from,edge tmp)
 {
     edges.push_back(tmp);

     int m = edges.size();

     v[);
 }

 void bfs1(void)
 {
     vis[] = ;

     queue<int> q;

     q.push();

     ;

     while (!q.empty())
     {
         int s = q.front();q.pop();

         ;i < v[s].size();i++)
         {
             int j = v[s][i];

             int to = edges[j].to;

             if (vis[to]) continue;

             vis[to] = ;

             dis[to] = dis[s] + ;

             q.push(to);

             if (to == n)
             {
                 f = ;
                 break;
             }
         }

         if (f) break;
     }
 }

 void bfs2()
 {
     vis[] = ;

     queue<int> q;

     q.push();

     ;

     while (!q.empty())
     {
         int s = q.front();q.pop();

         ;i < v[s].size();i++)
         {
             int j = v[s][i];

             int to = edges[j].to;

             int w = edges[j].cost;

             if (vis[to]) continue;

             if ((key[s] & w) < w) continue;

             key[to] |= w;
             key[to] |= key[s];

             vis[to] = ;

             dis[to] = dis[s] + ;

             q.push(to);

             if (to == n)
             {
                 f = ;
                 break;
             }
         }

         if (f) break;
     }
 }

 int main()
 {
     scanf("%d%d%d",&n,&m,&k);

     if (!k)
     {
         ;i < m;i++)
         {
             int x,y;

             scanf("%d%d",&x,&y);

             edge tmp = (edge){x,y,};

             adde(x,tmp);
         }

         bfs1();

         if (!vis[n]) printf("No Solution\n");
         else printf("%d\n",dis[n]);
     }
     else
     {
         ;i <= n;i++)
         {
             ;

             ;j <= k;j++)
             {
                 int x;

                 scanf("%d",&x);

                  << j);
             }

             key[i] = tmp;
         }

         ;i <= m;i++)
         {
             int x,y;

             scanf("%d%d",&x,&y);

             ;

             ;j <= k;j++)
             {
                 int x;

                 scanf("%d",&x);

                  << j);
             }

             edge e = (edge){x,y,tmp};

             adde(x,e);
         }

         bfs2();

         if (!vis[n]) printf("No Solution\n");
         else printf("%d\n",dis[n]);
     }

     ;
 }

计蒜客 2017 NOIP 提高组模拟赛(四)Day1 T2 小X的密室的更多相关文章

  1. 10-18 noip提高组模拟赛(codecomb)T1倍增[未填]

    T1只想到了找环,> <倍增的思想没有学过,所以看题解看得雨里雾里的(最近真的打算学一下! 题目出的挺好的,觉得noip极有可能出现T1T2T3,所以在此mark 刚开始T1以为是模拟,还 ...

  2. 10-18 noip提高组模拟赛(codecomb)T2贪心

    T2:找min:一直找最小的那个,直到a[i]-x+1小于0,就找次小的,以此类推: 求max,也是一样的,一直到最大的那个,直到次大的比之前最大的大,就找次大的: 这个模拟,可以用上priority ...

  3. HGOI20180815 (NOIP 提高组模拟赛 day2)

    Day 2 rank 11 100+35+30=165 本题是一道数论题,求ax+by=c的正整数对(x,y) x>=0并且y>=0 先说下gcd: 求a,b公约数gcd(a,b) 如gc ...

  4. 【洛谷】NOIP提高组模拟赛Day2【动态开节点/树状数组】【双头链表模拟】

    U41571 Agent2 题目背景 炎炎夏日还没有过去,Agent们没有一个想出去外面搞事情的.每当ENLIGHTENED总部组织活动时,人人都说有空,结果到了活动日,却一个接着一个咕咕咕了.只有不 ...

  5. 【洛谷】NOIP提高组模拟赛Day1【组合数学】【贪心+背包】【网络流判断是否满流以及流量方案】

    U41568 Agent1 题目背景 2018年11月17日,中国香港将会迎来一场XM大战,是世界各地的ENLIGHTENED与RESISTANCE开战的地点,某地 的ENLIGHTENED总部也想派 ...

  6. noip提高组模拟赛(QBXT)T2

    T2count题解 [ 问题描述]: 小 A 是一名热衷于优化各种算法的 OIER,有一天他给了你一个随机生成的 1~n 的排列, 并定 义区间[l,r]的价值为: \[ \huge C_{l,r}= ...

  7. [LUOGU] NOIP提高组模拟赛Day1

    题外话:以Ingress为题材出的比赛好评,绿军好评 T1 考虑枚举第\(i\)个人作为左边必选的一个人,那左边剩余\(i-1\)个人,选法就是\(2^{i-1}\),也就是可以任意选或不选,右侧剩余 ...

  8. l洛谷 NOIP提高组模拟赛 Day2

    传送门 ## T1 区间修改+单点查询.差分树状数组. #include<iostream> #include<cstdio> #include<cstring> ...

  9. HGOI2010816 (NOIP 提高组模拟赛 day1)

    Day1 210pts(含T1莫名的-10pts和T3莫名的-30pts) 100+70+40=210 rank 29 这道题第一眼看是字符串匹配问题什么KMP啊,又想KMP不会做啊,那就RK Has ...

随机推荐

  1. java设计模式系列之设计模式概要(1)

    一.什么是设计模式 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. ...

  2. 短视频 SDK 功能点技术实现方式详解

    第三方短视频解决方案作为快速切入短视频行业的首选方式,选择一款功能齐全.性能优异的短视频解决方案十分重要. 今天我们来谈谈短视频 SDK 6大重要功能点及其技术实现方式. 短视频拍摄 断点续拍 指在拍 ...

  3. [转载]dreamweaver代码提示失效

    原文地址:dreamweaver代码提示失效作者:云中雁 2007-03-23 12:19:22|  分类: 编程手记 |  标签:web2.0  javascript   |字号大中小 订阅 吴庆民 ...

  4. windows 下 Mutex和Critical Section 区别和使用

    Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的变量.对象或内存空间的访问.下面是其主要的异同点(不同的地方用黑色表示). Mutex Cri ...

  5. 关于在git添加远程地址的过程中遇到的问题

    问题产生的过程 我根据菜鸟教程的步骤,做了如下操作: 1.打开安装文件夹中的git-bash程序 2.设置username和email 3.添加远程地址 结果如下: 之后通过百度知道要先git ini ...

  6. 201521123062《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 Q1.clone方法 1.1 Object ...

  7. 201521123100 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...

  8. 201521123005 《Java程序设计》 第十周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...

  9. 201521123034《Java程序设计》第十三周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  10. 201521123066 《Java程序设计》第十一周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synch ...