國慶集訓D1T2 小W的房間
阿新 • • 發佈:2018-12-13
因為沒有邊權,所以廣搜+雜湊判重(以減少不必要的搜尋)。 用狀態壓縮的方式儲存鑰匙的狀態。 因為雜湊雜湊得不夠好T了,95分。 雜湊的時候要注意分析到底哪一些資訊是有用的,哪一些資訊是沒有用的,從而將更多冗餘的點壓縮在一起,從而降低執行時間。 具體地說 1.其實對於每個node來說,step是無關緊要的,因為只要是在同一個位置並且當前的鑰匙相同,那麼就是同一個狀態,並且step小的一定會先搜到,之後就通通丟掉不要。 2.並不需要deleteHash,理由同上。 另:雜湊的時候記憶體夠雜湊表儘量越大越好。
#include<bits/stdc++.h> #define rep(i,l,r) for(int i=(l);i<=(r);i++) #define per(i,l,r) for(int i=(r);i>=(l);i--) using namespace std; const int N=6e3,M=7e3,inf=1e9,base=13131,mod=16777215; struct node{ int nowkey,step,pos; }; int n,m,k,roomkey[N],a,ans=inf; int nxt[M],to[M],head[N],roadkey[M],len; int times[N]; node myh[mod]; int cnt[mod]; queue<node> q; void addedge(int u,int v,int rk){ nxt[++len]=head[u]; to[len]=v; head[u]=len; roadkey[len]=rk; } bool equal(node a,node b){ if(((a.nowkey==b.nowkey))&&(a.pos==b.pos)) return true; return false; } void myhash(node a){ int pos=(a.nowkey*base+a.pos*base*base)&mod; while((cnt[pos]>0)&&(equal(myh[pos],a)==false)) pos=(pos+1)&mod; cnt[pos]++; myh[pos]=a; } bool findhash(node a){ int pos=(a.nowkey*base+a.pos*base*base)&mod; while((cnt[pos]>0)){ if(equal(myh[pos],a)==true) return true; pos=(pos+1)&mod; } return false; } /*void deletehash(node a){ int pos=(a.nowkey*base+a.pos*base*base+a.step*base*base*base)&mod; while((cnt[pos]>0)&&(equal(myh[pos],a)==false)) pos=(pos+1)&mod; cnt[pos]--; }*/ int main(){ scanf("%d%d%d",&n,&m,&k); rep(i,1,n) rep(j,0,k-1) {//從最低位用起 scanf("%d",&a); roomkey[i]|=(a<<j); } rep(i,1,m){ int x,y,rk=0; scanf("%d%d",&x,&y); rep(j,0,k-1){ scanf("%d",&a); rk|=(a<<j); } addedge(x,y,rk); } node fir; fir.nowkey=roomkey[1]; fir.step=0; fir.pos=1; q.push(fir); while(!q.empty()){ node hd=q.front(); q.pop();// deletehash(hd); //printf("pos=%d\n",hd.pos); if(hd.pos==n){ ans=hd.step; break; } if(hd.step>30000) break; for(int i=head[hd.pos];i!=0;i=nxt[i]){ if((hd.nowkey&roadkey[i])==roadkey[i]){ node tmp; tmp.nowkey=(hd.nowkey|roomkey[to[i]]); tmp.pos=to[i]; tmp.step=hd.step+1; if(findhash(tmp)) continue; q.push(tmp); myhash(tmp); } } } if(ans==inf) printf("No Solution"); else printf("%d",ans); return 0; }