D 最短路变短了 最短路+思维
链接:https://ac.nowcoder.com/acm/contest/5026/D
思路:
换个思维想想,如果将一条边反向了会导致最短路变短的话,那个最短路就一定会经过这条反向的边,仔细想想是不是?于是我们就正向和方向建边跑spfa,spfa1起点是1,spfa2起点是n,对于一条边u->v来说,只要判断d2【u】+d1【v】+cost是否小于d1【n】即可。注意我们只要判断是否变短就可以了,至于是不是变得无法到达
————————————————
版权声明:本文为CSDN博主「qq_42479630」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42479630/java/article/details/105458364
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+10; 5 const int maxm=2e5+10; 6 const ll inf=1e18; 7 struct node 8 { 9 int v,w,nxt; 10 }G1[maxm],G2[maxm]; 11 int head1[maxn];int head2[maxn]; 12 int num1,num2; 13 ll dis1[maxn]; 14 ll dis2[maxn]; 15 int vis[maxn]; 16 int stou[maxm],stov[maxm],stow[maxm]; 17 void add1(int u,int v,int w) 18 { 19 G1[++num1].v=v;G1[num1].w=w;G1[num1].nxt=head1[u];head1[u]=num1; 20 } 21 void add2(int u,int v,int w) 22 { 23 G2[++num2].v=v;G2[num2].w=w;G2[num2].nxt=head2[u];head2[u]=num2; 24 } 25 void SPFA1(int u) 26 { 27 memset(vis,0,sizeof(vis)); 28 queue<int>q; 29 q.push(u); 30 dis1[u]=0; 31 vis[u]=1; 32 while(!q.empty()){ 33 int u=q.front(); 34 q.pop(); 35 vis[u]=0; 36 for(int i=head1[u];i;i=G1[i].nxt){ 37 int v=G1[i].v; 38 int w=G1[i].w; 39 if(dis1[v]>dis1[u]+w){ 40 dis1[v]=dis1[u]+w; 41 if(!vis[v]){ 42 vis[v]=1; 43 q.push(v); 44 } 45 } 46 } 47 } 48 49 } 50 void SPFA2(int u) 51 { 52 memset(vis,0,sizeof(vis)); 53 queue<int>q; 54 q.push(u); 55 dis2[u]=0; 56 vis[u]=1; 57 while(!q.empty()){ 58 int u=q.front(); 59 q.pop(); 60 vis[u]=0; 61 for(int i=head2[u];i;i=G2[i].nxt){ 62 int v=G2[i].v; 63 int w=G2[i].w; 64 if(dis2[v]>dis2[u]+w){ 65 dis2[v]=dis2[u]+w; 66 if(!vis[v]){ 67 vis[v]=1; 68 q.push(v); 69 } 70 } 71 } 72 } 73 74 } 75 void init() 76 { 77 for(int i=0;i<=maxn-2;i++){ 78 dis1[i]=inf; 79 dis2[i]=inf; 80 } 81 } 82 int main() 83 { 84 init(); 85 int n,m; 86 scanf("%d%d",&n,&m); 87 for(int i=1;i<=m;i++){ 88 int u,v,w; 89 scanf("%d%d%d",&u,&v,&w); 90 add1(u,v,w); 91 add2(v,u,w); 92 stou[i]=u; 93 stov[i]=v; 94 stow[i]=w; 95 } 96 SPFA1(1); 97 SPFA2(n); 98 int q; 99 scanf("%d",&q); 100 while(q--){ 101 int tmp; 102 scanf("%d",&tmp); 103 int u=stou[tmp]; 104 int v=stov[tmp]; 105 int w=stow[tmp]; 106 if(dis1[v]+dis2[u]+w>=dis1[n]) printf("NO\n"); 107 else printf("YES\n"); 108 } 109 }