rt
我和题解不太一样,没有删点啊,建新图啊,建图的时候就反着建的,然后算法里也没有加别的边。但还是要开2倍大小不然第二个点WA了(不是应该RE的说吗?)
求大佬解答
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN=2e4+10,MAXM=4e5+10,INF=2e9;
struct Edge{
int u,v;
}edge[MAXM];
int first[MAXN],next[MAXM],tot;
int n,m,s,t;
int arrive[3][MAXN],check[MAXN];
void addedge(int u,int v){
tot++;
edge[tot].u=u;edge[tot].v=v;
next[tot]=first[u];
first[u]=tot;
}
void tryarrive(int start,int ans[]){
int vis[MAXN];
queue<int>q;
vis[start]=1;
ans[start]=1;
q.push(start);
while(!q.empty()){
int u=q.front();q.pop();
for(int j=first[u];j;j=next[j]){
int v=edge[j].v;
if(!vis[v]){
vis[v]=1;
ans[v]=1;
q.push(v);
}
}
}
}
void findtrail(int start,int ans[]){
for(int i=1;i<=n;i++){
ans[i]=INF;
}
ans[start]=0;
queue<int>q;
if(check[start])q.push(start);
while(!q.empty()){
int u=q.front();q.pop();
for(int j=first[u];j;j=next[j]){
int v=edge[j].v;
if(!check[v])continue;
if(ans[u]+1<ans[v]){
ans[v]=ans[u]+1;
q.push(v);
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
addedge(y,x);
}
cin>>s>>t;
//预处理每个点和s/t是否连通
tryarrive(s,arrive[0]);
tryarrive(t,arrive[1]);
//预处理这个点是否能选
for(int i=1;i<=n;i++){
check[i]=1;
}
for(int i=1;i<=n;i++){
int& u=i;
if(arrive[0][u] || arrive[1][u])continue;
for(int j=first[u];j;j=next[j]){
int v=edge[j].v;
check[v] = 0;
}
}
//找一条从t到s的路径(因为倒着建图了)
findtrail(t,arrive[2]);
if(arrive[2][s]==INF){
printf("-1");
}else{
printf("%d",arrive[2][s]);
}
return 0;
}