我们无论怎么走,都是要从此点沿最短路径走到终点,所以我们以n为原点跑两边dijkstra就可以了;
而抱怨数可以根据之前跑出来的东西新建一个图,然后跑最短路就好了;
#include <bits/stdc++.h>
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
int head[2000010],cnt;
class littlestar{
public:
int to;
int nxt;
int w1,w2;
int w;
void add(int u,int v,int gg1,int gg2){
to=v;
nxt=head[u];
w1=gg1; w2=gg2;
head[u]=cnt;
}
}star[2000010];
int n,m;
priority_queue<pair<int,int> > q;
int dis[2000010],vis[2000010];
void dijkstra1()
{
memset(dis,0x3f,sizeof(dis));
q.push(make_pair(0,n));
dis[n]=0;
while(q.size()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis[v]>dis[u]+star[i].w1){
dis[v]=dis[u]+star[i].w1;
q.push(make_pair(-dis[v],v));
}
}
}
}
int dis2[2000010];
void dijkstra2()
{
memset(vis,0,sizeof(vis));
memset(dis2,0x3f,sizeof(dis2));
q.push(make_pair(0,n));
dis2[n]=0;
while(q.size()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis2[v]>dis2[u]+star[i].w2){
dis2[v]=dis2[u]+star[i].w2;
q.push(make_pair(-dis2[v],v));
}
}
}
}
void dijkstra()
{
memset(vis,0,sizeof(vis));
memset(dis2,0x3f,sizeof(dis2));
q.push(make_pair(0,n));
dis2[n]=0;
while(q.size()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis2[v]>dis2[u]+star[i].w){
dis2[v]=dis2[u]+star[i].w;
q.push(make_pair(-dis2[v],v));
}
}
}
}
int main()
{
cin>>n>>m;
inc(i,1,m){
int a,b,p,q;
scanf("%d%d%d%d",&a,&b,&p,&q);
star[++cnt].add(b,a,p,q);
}
dijkstra1();
dijkstra2();
inc(u,1,n){
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis[v]!=dis[u]+star[i].w1) ++star[i].w;
if(dis2[v]!=dis2[u]+star[i].w2) ++star[i].w;
}
}
dijkstra();
cout<<dis2[1];
}