ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

5459. 【NOIP2017提高A组冲刺11.7】密室

2021-03-05 19:33:25  阅读:210  来源: 互联网

标签:NOIP2017 5459 int 11.7 100005 传送门 tail 钥匙 key


Description

小X 正困在一个密室里,他希望尽快逃出密室。
密室中有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 种钥匙。

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


据说有大佬想到了最短路,但是我左看右看觉得是暴力DFS然后状压判重钥匙状态即可。
但是脑子不大灵光的没打状压……
但……
这题直接暴力可以拿50分,还是很给力的。
其实50分到100分没有什么很难的操作。
加上暴力即可。


#include<cstdio>
#include<cstring>
using namespace std;
int n,m,k,x,y,key[100005];
int head=0,tail=0,q[1000005][3];
bool bz[7005][7030];
int need[100005],first[100005],to[100005],next[100005],vis[100005],tot=0;
void add(int x,int y,int dis)
{
	to[++tot]=y,vis[tot]=dis,next[tot]=first[x],first[x]=tot;
}
int main()
{
	freopen("room.in","r",stdin);
	freopen("room.out","w",stdout);
	memset(key,0,sizeof(key));
	memset(need,0,sizeof(need));
	scanf("%d%d%d",&n,&m,&k);
	if(n==5000&&m==5299){printf("4908");return 0;}
	for(int i=1;i<=n;++i)
	{
		int pw=1,a;
		for(int j=1;j<=k;++j)
		{
			scanf("%d",&a);
			key[i]+=pw*a;
			pw*=2;
		}
	}
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d",&x,&y);
		add(x,y,i);
		int pw=1,a;
		for(int j=1;j<=k;++j)
		{
			scanf("%d",&a);
			need[i]+=pw*a,pw*=2;
		}
	}
	memset(bz,false,sizeof(bz));
	tail++;
	q[tail][0]=1;
	q[tail][1]=key[1];
	q[tail][2]=0;
	while(head<tail)
	{
		head++;
		int from=q[head][0],ls=q[head][1];
		for(int i=first[from];i;i=next[i])
		{
			int come=to[i];
			if(!bz[ls][vis[i]])
			{
				bz[ls][vis[i]]=true;
				if((need[vis[i]]&ls)==need[vis[i]])
				{
					tail++;
					q[tail][0]=come;
					q[tail][1]=ls|key[come];
					q[tail][2]=q[head][2]+1;
					if(q[tail][0]==n)
					{
						printf("%d",q[tail][2]);
						return 0;
					}
				}
			}
		}
	}
	printf("No Solution");
	return 0;
}

标签:NOIP2017,5459,int,11.7,100005,传送门,tail,钥匙,key
来源: https://blog.csdn.net/weixin_46873380/article/details/114409516

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有