我们无论怎么走,都是要从此点沿最短路径走到终点,所以我们以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]; }