对于每一条不同的地铁线路进行拆点,生成新的节点,连边,然后对于同一地铁站内的不同节点按照他们所属的地铁线的编号从小到大连接,最后跑最短路,建图是难点,我们可以对同一地铁线的不同边进行统一处理,同时再依次添加到相应的地站的集合中,因为是顺序插入,所以本身就是从小到大的了,具体见代码。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <set>
#include <queue>
using namespace std;
const int INF=1e9+10;
const double EPS = 1e-10;
typedef unsigned long long ll;
const int mod=1e9+7;
typedef pair<ll,int> P;
int n,m,tot;
vector<pair<int,int> >st[100005];
struct edge1{
int u,v,w;
};
vector<edge1> line[100005];
ll linf=(1LL<<63)-1;
ll d[200005];
struct edge{
int v,w;
};
vector<edge> g[200005];
void add_edge(int u,int v,int w){
g[u].push_back((edge){v,w});
g[v].push_back((edge){u,w});
}
void dijkstra(){
for(int i=0;i<tot;i++)
d[i]=linf;
priority_queue<P,vector<P>,greater<P> >que;
/* d[s]=0;
que.push(P(0,s));*/
for(int i=0;i<st[1].size();i++){
int u=st[1][i].first;
d[u]=0;
que.push(P(0,u));
}
while(!que.empty()){
P p=que.top(); que.pop();
int v=p.second;
if(d[v]<p.first) continue;
//printf("11 %d %d %d\n",p.first,v,g[v].size() );
for(int i=0;i<g[v].size();i++){
edge e=g[v][i];
//printf("222 %d %d\n",e.v,e.w );
if(d[e.v]>d[v]+e.w){
d[e.v]=1LL*d[v]+e.w;
que.push(P(d[e.v],e.v));
}
}
}
//return d[cnt];
}
void init(){
for(int i=0;i<=n;i++)
line[i].clear(),st[i].clear();
}
int main(){
//freopen("out.txt","w",stdout);
while(scanf("%d %d",&n,&m)!=EOF){
//printf("m %d n %d\n",m,n );
for(int i=0;i<m;i++){
int u,v,l,w;
scanf("%d %d %d %d",&u,&v,&l,&w);
line[l].push_back((edge1){u,v,w});
}
tot=0;
for(int i=1;i<=n;i++){
for(int j=0;j<line[i].size();j++){
//printf("%d %d\n",i,j );
int u=line[i][j].u,v=line[i][j].v,w=line[i][j].w;
if(!st[u].size()||st[u].back().second!=i){
st[u].push_back(make_pair(tot++,i));
}
if(!st[v].size()||st[v].back().second!=i){
st[v].push_back(make_pair(tot++,i));
}
add_edge(st[u].back().first,st[v].back().first,w);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<st[i].size();j++){
int u=st[i][j-1].first,v=st[i][j].first;
int w=st[i][j].second-st[i][j-1].second;
add_edge(u,v,w);
}
}
ll ans=linf;
dijkstra();
for(int i=0;i<st[n].size();i++){
int u=st[n][i].first;
ans=min(ans,d[u]);
}
for(int i=0;i<tot;i++)
g[i].clear();
init();
printf("%lld\n",ans);
}
return 0;
}