分層圖+最短路 小雨坐地鐵

小雨坐地鐵

在這裏插入圖片描述


分層圖是什麼?

每個地鐵線可以作爲一層圖,這一層所涉及的點都要重新編號(相當於離散化,或者叫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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章