小W與選座
阿新 • • 發佈:2018-12-16
根據每個人,列舉下他有多少種方案,然後跑一個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