密室中有N 個房間,初始時,小X 在1 號房間,而出口在N 號房間。
密室的每一個房間中可能有著一些鑰匙和一些傳送門,一個傳送門會單向地創造一條從房間X 到房間Y 的通道。另外,想要通過某個傳送門,就必須具備一些種類的鑰匙(每種鑰匙都要有才能通過)。幸運的是,鑰匙在開啟傳送門的封印後,並不會消失。
然而,通過密室的傳送門需要耗費大量的時間,因此,小X 希望通過儘可能少的傳送門到達出口,你能告訴小X 這個數值嗎?
另外,小X 有可能不能逃出這個密室,如果是這樣,請輸出"No Solution"。
一開始以為是一個搜尋果斷跳,結果看到資料範圍發現可以做
發現k很小,這就是一個傻逼狀壓分層圖啊
而且還不帶邊權的,直接bfs,dijk都不用了
#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct nod{ int x,k; } c;
struct edge{ int v,c,nt; }G[10010];
queue<nod> q;
int d[1110][5010],w[5010],h[5010];
int n,m,k,cnt=0,ans=1<<30;
inline void adj(int x,int y,int c){
G[++cnt]=(edge){y,c,h[x]}; h[x]=cnt;
}
inline int get(){
int s=0;
for(int x,i=0;i<k;++i) scanf("%d",&x),s|=x<<i;
return s;
}
int main(){
freopen("room.in","r",stdin);
freopen("room.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;++i) w[i]=get();
for(int x,y,i=1;i<=m;++i){
scanf("%d%d",&x,&y);
adj(x,y,get());
}
memset(d,-1,sizeof d);
d[w[1]][1]=0; q.push((nod){1,w[1]});
for(int x,y;!q.empty();q.pop()){
c=q.front(); x=c.x; y=c.k;
for(int v,i=h[x];i;i=G[i].nt)
if(((y&G[i].c)==G[i].c)&&d[y|w[G[i].v]][v=G[i].v]==-1){
d[y|w[v]][v]=d[y][x]+1; q.push((nod){v,y|w[v]});
}
}
for(int i=0;i<(1<<k);++i) if(~d[i][n]) ans=min(ans,d[i][n]);
if(ans==1<<30) puts("No Solution"); else printf("%d\n",ans);
}