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 }
View Code

 

posted @ 2020-05-18 16:08  古比  阅读(160)  评论(0编辑  收藏  举报