当有了另外的限制条件的时候(必须要有对应的剑),就要考虑分层图,每一层都对用了一种现在有的剑的状态,当然不是建2^13张图
而是多开一维,表示现在有的剑,到了一条路,要判断是否要求的剑都有了,可以用if((edge[i].mst|mst)!=mst) continue来判断
每次只有当弹出队首的,才更新d[u][mst]的mst,意思是只有这条路考虑清楚了,才能再往下走,
不过考试好像考了,我也写不出来的样子,好像也不是很会考的样子
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<stack> 8 #include<set> 9 #include<map> 10 using namespace std; 11 #define mpr(x,y,z) make_pair(make_pair(x,y),z) 12 int read(){ 13 int f=1,x=0;char s=getchar(); 14 while(s<'0'||s>'9'){if(s=='-') f=-1;s=getchar();} 15 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 16 return x*f; 17 } 18 const int maxn=207; 19 const int maxm=3007; 20 const int maxp=10007; 21 const int INF=0x7f7f7f7f; 22 typedef pair<int,int>pii; 23 priority_queue<pair<pii,int>,vector<pair<pii,int> >,greater<pair<pii,int> > > q; 24 int n,m,p,k,num; 25 int s[maxn],head[maxn],d[maxn][maxp]; 26 bool vis[maxn][maxp]; 27 struct Edge{ 28 int nxt,to,dis,mst; 29 }edge[maxm<<1]; 30 void add(int from,int to,int dis,int mst){ 31 edge[++num].nxt=head[from]; 32 edge[num].to=to; 33 edge[num].dis=dis; 34 edge[num].mst=mst; 35 head[from]=num; 36 } 37 int Dij(){ 38 memset(d,INF,sizeof(d)); 39 memset(vis,false,sizeof(vis)); 40 d[1][0]=0;q.push(mpr(0,1,0)); 41 while(!q.empty()){ 42 int w=q.top().first.first; 43 int u=q.top().first.second; 44 int mst=q.top().second; 45 q.pop(); 46 if(u==n) return w; 47 if(vis[u][mst]) continue; 48 vis[u][mst]=true;mst|=s[u]; 49 for(int i=head[u];i;i=edge[i].nxt){ 50 int v=edge[i].to; 51 if((edge[i].mst|mst)!=mst) continue; 52 if(d[v][mst]>w+edge[i].dis){ 53 d[v][mst]=w+edge[i].dis; 54 q.push(mpr(d[v][mst],v,mst)); 55 } 56 } 57 } 58 return -1; 59 } 60 int main(){ 61 n=read();m=read();p=read();k=read(); 62 for(int i=1;i<=k;i++){ 63 int u,v,w;u=read();v=read(); 64 for(int j=1;j<=v;j++){ 65 w=read();s[u]|=(1<<(w-1)); 66 } 67 } 68 for(int i=1;i<=m;i++){ 69 int x,y,t,s,w; 70 x=read();y=read();t=read();s=read(); 71 int tmp=0; 72 for(int i=1;i<=s;i++){ 73 w=read(); 74 tmp|=(1<<(w-1)); 75 } 76 add(x,y,t,tmp);add(y,x,t,tmp); 77 } 78 cout<<Dij()<<endl; 79 return 0; 80 }