Luogu P3489 [POI2009]WIE-Hexer 最短路

https://www.luogu.org/problemnew/show/P3489

普通的最短路,不过我觉得这个复杂度按道理来说边数不应该是m*2^13吗,不知道是数据比较水还是实际上能证明复杂度低一些。

代码如下

#include<bits/stdc++.h>
using namespace std; 
const int maxn = 210; 
#define pa pair<int,int>
int n,m,p,k;
int dis[maxn][8200]={},kn[maxn]={};
bool vis[maxn][8200]={};
priority_queue< pa , vector< pa > , greater< pa > >q;
struct en{
	int y,v,t,next;
}e[8000];
int head[maxn]={},tot=0;
void init(int x, int y, int v, int t){
	e[++tot].next=head[x]; e[tot].y=y;
	e[tot].t=t; e[tot].v=v; head[x]=tot;
}
void dji(){
	q.push(make_pair(0,8200+kn[1]));dis[1][kn[1]]=0;
	int flag=0,ans=dis[2][0];
	while(!q.empty()){
		int x=q.top().second;
		int knf=x%8200;x/=8200;q.pop();
		if(x==n){flag=1;cout<<dis[x][knf]<<endl;break;} 
		if(vis[x][knf])continue;
		vis[x][knf]=1; 
		for(int i=head[x];i;i=e[i].next){
			int y=e[i].y;
			if((e[i].v|knf)==knf){
				if(e[i].t+dis[x][knf]<=dis[y][knf|kn[y]]){
					dis[y][knf|kn[y]]=e[i].t+dis[x][knf];
					vis[y][knf|kn[y]]=0;
					q.push( make_pair( dis[y][knf|kn[y]],y*8200+(knf|kn[y]) ) );
				}
			}
		}
	}
	if(!flag)cout<<-1<<endl;
}
int main(){
	scanf("%d%d%d%d",&n,&m,&p,&k);
	memset(dis,63,sizeof(dis));
	for(int i=1;i<=k;++i){
		int x,y,z; scanf("%d%d",&x,&y); 
		for(int j=1;j<=y;++j){
			scanf("%d",&z); kn[x]|=1<<(z-1);
		}
	}
	for(int i=1;i<=m;++i){
		int x,y,z,t,w,v=0; scanf("%d%d%d%d",&x,&y,&t,&z);
		for(int j=1;j<=z;j++){
			scanf("%d",&w); v|=1<<(w-1);
		} init(x,y,v,t); init(y,x,v,t);
	}
	dji();
	return 0;	
}

  

posted @ 2019-06-19 21:47  鲸头鹳  阅读(165)  评论(0编辑  收藏  举报