小雨坐地鐵
分層圖是什麼?
每個地鐵線可以作爲一層圖,這一層所涉及的點都要重新編號(相當於離散化,或者叫hash),這樣一來每層的點都沒有聯繫了,那麼換線怎麼辦?
這個時候可以建立虛點,每個點都與沒有重新編號的點連接,代表出站或者入站;
圖建完了就是裸的最短路;
代碼:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=1000100;
const int M=50100;
const LL mod=10007;
int n,m,s,t,head[N],cnt,dis[N];
bool vis[N];
struct Node{
int to,nex,w;
}edge[N*2];
void add(int p,int q,int w){edge[cnt].w=w,edge[cnt].to=q,edge[cnt].nex=head[p],head[p]=cnt++;}
struct node{
int fi,se;
bool operator < (const node& rhs) const{return fi>rhs.fi;}
};
void dij(){
priority_queue<node>qu;
for(int i=1;i<=2*n*m;i++) dis[i]=2e9,vis[i]=false;
dis[s]=0;
qu.push(node{0,s});
while(!qu.empty()){
node n1=qu.top();
qu.pop();
int p=n1.se;
if(vis[p]) continue;
vis[p]=true;
for(int i=head[n1.se];~i;i=edge[i].nex){
int q=edge[i].to;
if(dis[q]>dis[p]+edge[i].w){
dis[q]=dis[p]+edge[i].w;
qu.push(node{dis[q],q});
}
}
}
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=m;i++){
int a,b,c,x,pre;scanf("%d%d%d",&a,&b,&c);
for(int j=1;j<=c;j++){
scanf("%d",&x);
if(j!=1) add(n*i+x,pre,b),add(pre,n*i+x,b);
pre=n*i+x,add(n*i+x,x,0),add(x,n*i+x,a);
}
}
dij();
// for(int i=1;i<=m*n;i++) cout<<dis[i]<<endl;
if(dis[t]==2e9) printf("-1\n");
else printf("%d\n",dis[t]);
return 0;
}