小W与施工
小W与施工
小W与施工
这道题要考虑到S到T的最短路就是一个dist(S,u)+dist(v,T)+w组成的有向无环图。那么一个S到T的最短路仅是一条最短路图上S到T的路径。
这题的主要思想就是

1.如果一条边不在最短路图上,则这条边删掉一定不会对最短路产生任何影响。

2.如果一条边在最短路图上,则考虑这条边删掉之后这个最短路图还连不连通就行了。
(当时竟然没想到qwq)

如果一条边被删了就不连通,那么这条边肯定就是原图变成无向图之后的割边,跑一遍Tarjan就行了。

我一开始想到的dijkstra,应为看到了最短路麻,所以整个思路都偏了,应为这个有重边和自环。

#include<bits/stdc++.h>
using namespace std;
#define N 200005
#define inf 2147483646
int n,m,q,s,t,cnt=0;
int diss[N],dist[N],vis[N];
struct cmp{
 int len,x;
 bool operator <(const cmp &a)const{
  return a.len<len;
 }
};
priority_queue<cmp>Q;
int head[N];
struct aa{
 int tt,nxtt,ten;
}ed[N<<1];
void add(int x,int y,int z){
 ed[++cnt].tt=y;
 ed[cnt].nxtt=head[x];
 ed[cnt].ten=z;
 head[x]=cnt;
}
int heads[N];
struct ee
{
 int to,nxt,en,hao;
}edg[N];
void addy(int x,int y,int z,int ii){
 edg[++cnt].to=y;
 edg[cnt].nxt=heads[x];
 edg[cnt].hao=ii;
 edg[cnt].en=z;
 heads[x]=cnt;
}
void djis(int xs){
 cmp gg;
 for(int i=1;i<=n;i++)diss[i]=inf,vis[i]=0;
 gg.x=xs;gg.len=0;
 Q.push(gg);diss[xs]=0;
 while(!Q.empty()){
  cmp u=Q.top();
  Q.pop();
  if(vis[u.x])continue;
  vis[u.x]=1;
  for(int i=heads[u.x];i;i=edg[i].nxt){
   int ve=edg[i].to;
   if(!vis[ve]&&diss[ve]>diss[u.x]+edg[i].en){
    diss[ve]=diss[u.x]+edg[i].en;
    gg.x=ve;gg.len=diss[ve];
    Q.push(gg);
   }
  }
 }
}
int hea[N],cnty=0;
struct ab{
 int t,nx,e;
}edd[N<<1];
void addx(int x,int y,int z){
 edd[++cnty].t=y;
 edd[cnty].nx=hea[x];
 edd[cnty].e=z;
 hea[x]=cnty;
}
void djit(int xt){
 cmp gg;
 for(int i=1;i<=n;i++)dist[i]=inf,vis[i]=0;
 gg.x=xt;gg.len=0;
 Q.push(gg);dist[xt]=0;
 while(!Q.empty()){
  cmp u=Q.top();
  Q.pop();
  if(vis[u.x])continue;
  vis[u.x]=1;
  for(int i=hea[u.x];i;i=edd[i].nx){
   int ve=edd[i].t;
   if(!vis[ve]&&dist[ve]>dist[u.x]+edd[i].e){
    dist[ve]=dist[u.x]+edd[i].e;
    gg.x=ve;gg.len=dist[ve];
    Q.push(gg);
   }
  }
 }
}
int dfn[N],loww[N],f[N],tim=0;
void tarjan(int u,int fa){
 dfn[u]=loww[u]=++tim;
 for(int i=head[u];i;i=ed[i].nxtt){
  int ve=ed[i].tt;
  if(!dfn[ve]){
   tarjan(ve,ed[i].ten);
   loww[u]=min(loww[ve],loww[u]);
  }
  else if(ed[i].ten!=fa) loww[u]=min(loww[u],dfn[ve]);
 }
 if(dfn[u]==loww[u])f[fa]=1;
}
int main()
{
 scanf("%d%d%d%d%d",&n,&m,&q,&s,&t);
 for(int x,y,z,i=1;i<=m;i++){
  scanf("%d%d%d",&x,&y,&z);
  addy(x,y,z,i);
  addx(y,x,z);
 }
 djis(s);djit(t);
 int min_len=diss[t];
  cnt=0;
 for(int i=1;i<=n;i++)
  for(int j=heads[i];j;j=edg[j].nxt){
   int ve=edg[j].to;
   if(diss[i]+edg[j].en+dist[ve]==min_len){
    add(i,ve,edg[j].hao);
    add(ve,i,edg[j].hao);
   }
    
  }
 tarjan(1,-1);
 for(int x,i=1;i<=q;i++)
 {
  scanf("%d",&x);
  if(!f[x]) puts("NO");
  else puts("YES");
 }
  return 0;
}

来源:zr

相关文章:

  • 2021-12-15
  • 2022-01-20
  • 2022-12-23
  • 2021-12-26
  • 2022-12-23
  • 2021-07-07
  • 2022-12-23
  • 2022-02-15
猜你喜欢
  • 2021-04-14
  • 2021-06-24
  • 2021-05-13
  • 2021-10-17
  • 2021-12-18
  • 2021-07-06
  • 2021-10-08
相关资源
相似解决方案