1. 程式人生 > >小W與選座

小W與選座

在這裡插入圖片描述 在這裡插入圖片描述 根據每個人,列舉下他有多少種方案,然後跑一個dijkstra,中間需要tarjan縮點,否則會超時

#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