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; }