Rt,这个题我的思路是:
先跑一遍p的最短路,再跑一遍q的最短路,最后每一条边统计它们的警告次数,以它们的警告次数为边权再建一个图,最后跑出来的最短路dis[n]
受警告次数最少,输出它
但是我这个样例还没有过,有没有大佬帮我耐心看看qwq
虽然代码有一定的码量,但很多都是一样的
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5,M=5e4+5,INF=2147483647;
struct node{
int from,to,dis,next;
}Edge[M];
struct Pair{
int now,dis;
bool operator <(const Pair &x) const
{
return x.dis<dis;
}
};
int disp[N],disq[N],disg[N],head[N],u[N],v[N],P[N],Q[N];
int n,m,tot;
bool vis[N];
inline int read()
{
int x=0;
bool w=0;
char c=getchar();
while(!isdigit(c))
w|=c=='-',c=getchar();
while(isdigit(c))
x=(x<<1)+(x<<3)+(c^48),c=getchar();
return w?-x:x;
}
inline void add(int u,int v,int w)
{
Edge[++tot].to=v;
Edge[tot].from=u;
Edge[tot].dis=w;
Edge[tot].next=head[u];
head[u]=tot;
}
inline void Dijkstra_p()
{
for(register int i=1;i<=n;++i)
disp[i]=INF;
memset(vis,0,sizeof(vis));
priority_queue<Pair> q;
q.push(Pair{1,0});
while(!q.empty())
{
int u=q.top().now;q.pop();
if(vis[u]) continue;
vis[u]=1;
for(register int i=head[u];i;i=Edge[i].next)
{
int v=Edge[i].to,w=Edge[i].dis;
if(disp[u]+w<disp[v])
{
disp[v]=disp[u]+w;
q.push(Pair{v,disp[v]});
}
}
}
}
inline void Dijkstra_q()
{
for(register int i=1;i<=n;++i)
disq[i]=INF;
memset(vis,0,sizeof(vis));
priority_queue<Pair> q;
q.push(Pair{1,0});
while(!q.empty())
{
int u=q.top().now;q.pop();
if(vis[u]) continue;
vis[u]=1;
for(register int i=head[u];i;i=Edge[i].next)
{
int v=Edge[i].to,w=Edge[i].dis;
if(disq[u]+w<disq[v])
{
disq[v]=disq[u]+w;
q.push(Pair{v,disq[v]});
}
}
}
}
inline void Dijkstra_g()
{
for(register int i=1;i<=n;++i)
disg[i]=INF;
memset(vis,0,sizeof(vis));
priority_queue<Pair> q;
q.push(Pair{1,0});
while(!q.empty())
{
int u=q.top().now;q.pop();
if(vis[u]) continue;
vis[u]=1;
for(register int i=head[u];i;i=Edge[i].next)
{
int v=Edge[i].to,w=Edge[i].dis;
if(disg[u]+w<disg[v])
{
disg[v]=disg[u]+w;
q.push(Pair{v,disg[v]});
}
}
}
}
inline void Clear()
{
memset(head,0,sizeof(head));
memset(Edge,0,sizeof(Edge));
tot=0;
}
signed main()
{
n=read(),m=read();
for(register int i=1;i<=m;++i)
{
u[i]=read(),v[i]=read();
P[i]=read(),Q[i]=read();
}
for(register int i=1;i<=m;++i)
add(u[i],v[i],P[i]);
Dijkstra_p();
Clear();
for(register int i=1;i<=m;++i)
add(u[i],v[i],Q[i]);
Dijkstra_q();
Clear();
for(register int i=1;i<=m;++i)
{
int sum=0;
if(disp[Edge[i].from]+P[i]!=disp[Edge[i].to]) ++sum;
if(disq[Edge[i].from]+Q[i]!=disq[Edge[i].to]) ++sum;
add(Edge[i].from,Edge[i].to,sum);
}
Dijkstra_g();
printf("%d",disg[n]);
return 0;
}