1. 程式人生 > >國慶集訓D1T2 小W的房間

國慶集訓D1T2 小W的房間

因為沒有邊權,所以廣搜+雜湊判重(以減少不必要的搜尋)。 用狀態壓縮的方式儲存鑰匙的狀態。 因為雜湊雜湊得不夠好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;
}