分层图思想;
一共有m条线路,则相当于m+1层;最后一层是设立虚点;
每层只需与最后一层相连即可;最后一层的点相当于中转站;
#include<bits/stdc++.h> #include<queue> using namespace std; const int maxn=1100; int head[maxn*maxn],cnt,m,n,dis[maxn*maxn]; struct node{ bool operator()(int x,int y){ return dis[x]>dis[y]; } }; priority_queue<int,vector<int>,node > q; struct edge{ int nx,to,w; }edge[maxn*maxn*2]; void add(int u,int v,int w) { edge[++cnt].nx=head[u]; edge[cnt].to=v; edge[cnt].w=w; head[u]=cnt; } void dijkstra(int s)//最短路算法 { dis[s]=0; q.push(s); while(!q.empty()) { int u=q.top(); q.pop(); for(int i=head[u];i;i=edge[i].nx) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].w) { dis[v]=dis[u]+edge[i].w; q.push(v); } } } } int main() { memset(dis,0x3f3f3f3f,sizeof(dis)); int s,t; cin>>n>>m>>s>>t; for(int i=1;i<=m;i++) { int a,b,c; cin>>a>>b>>c; int last = -1;//记录上一站 for(int j=1;j<=c;j++) { int x; cin>>x; if(last!=-1) { add((i-1)*n+x, (i-1)*n+last, b); //站与站之间花费b add((i-1)*n+last, (i-1)*n+x, b); } add((i-1)*n+x, m*n+x, 0);//每一层到最后一层花费为0 add(m*n+x, (i-1)*n+x, a);//最后一层去上面层花费a last = x; } } dijkstra(s+m*n); if(dis[t+m*n]>=0x3f3f3f3f) cout<<-1; else cout<<dis[t+m*n]; return 0; }