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

来源:互联网 发布:易语言写软件 编辑:程序博客网 时间:2024/05/29 17:46

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

Data Constraint

Data Constraint

Solution

  • 看到 k10 ,就想到状压DP——二进制状态!

  • 于是考虑从起点开始做一遍SPFA,用一个二维状态存即可(位置和状态)。

  • 但由于边权为 1 ,没有松弛操作,所以只需 BFS 一遍,输出终点答案即可。

Code

#include<cstdio>#include<cstring>using namespace std;const int N=6001;struct data{    int x,y;}q[N*1000];int tot,ans=1e9;int first[N],next[N],en[N],w[N];int a[N],dis[N][1025];inline int read(){    int X=0,w=1; char ch=0;    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();    return X*w;}inline int min(int x,int y){    return x<y?x:y;}inline void insert(int x,int y,int z){    next[++tot]=first[x];    first[x]=tot;    en[tot]=y;    w[tot]=z;}int main(){    int n=read(),m=read(),k=read();    for(int i=1;i<=n;i++)        for(int j=0;j<k;j++) a[i]+=read()<<j;    for(int i=1;i<=m;i++)    {        int x=read(),y=read(),z=0;        for(int j=0;j<k;j++) z+=read()<<j;        insert(x,y,z);    }    memset(dis,60,sizeof(dis));    int l=dis[1][a[1]]=0,r=1;    q[1].x=1,q[1].y=a[1];    while(l<r)    {        data now=q[++l],t;        for(int i=first[now.x];i;i=next[i])            if((now.y&w[i])==w[i] && dis[now.x][now.y]+1<dis[en[i]][now.y|a[en[i]]])            {                dis[en[i]][now.y|a[en[i]]]=dis[now.x][now.y]+1;                if(en[i]==n) ans=min(ans,dis[en[i]][now.y|a[en[i]]]);                t.x=en[i],t.y=now.y|a[en[i]];                q[++r]=t;            }    }    if(ans==1e9) puts("No Solution"); else printf("%d",ans);    return 0;}
原创粉丝点击