方向dfs判定是否可行,spfa跑最短路。
noip水题,wa好几次。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 10000 + 10; const int maxm = 200000 + 10; int g[maxn],v[maxm],next[maxm],eid; int g1[maxn],v1[maxm],next1[maxm],eid1; int d[maxn],q[maxn*10]; int n,m,S,T; bool vis[maxn],able[maxn],ok[maxn],inque[maxn]; void addedge(int a,int b) { v[eid]=b; next[eid]=g[a]; g[a]=eid++; } void add(int a,int b) { v1[eid1]=b; next1[eid1]=g1[a]; g1[a]=eid1++; } void dfs(int u) { vis[u]=ok[u]=1; for(int i=g1[u];~i;i=next1[i]) if(!vis[v1[i]]) dfs(v1[i]); } void spfa() { int l=0,r=0,u; memset(d,0x3f,sizeof(d)); d[S]=0; q[r++]=S; while(l<r) { u=q[l++]; for(int i=g[u];~i;i=next[i]) if(able[v[i]] && d[v[i]] > d[u]+1) { d[v[i]]=d[u]+1; if(!inque[v[i]]) { q[r++]=v[i]; inque[v[i]]=1; } } inque[u]=0; } } int main() { memset(g,-1,sizeof(g)); memset(g1,-1,sizeof(g1)); scanf("%d%d",&n,&m); for(int i=1,x,y;i<=m;i++) { scanf("%d%d",&x,&y); if(x!=y) { addedge(x,y); add(y,x); } } scanf("%d%d",&S,&T); memset(able,1,sizeof(able)); dfs(T); for(int u=1;u<=n;u++) { for(int i=g[u];~i;i=next[i]) if(!ok[v[i]]) { able[u]=0; break; } } spfa(); if(d[T]>=n) printf("-1\n"); else printf("%d\n",d[T]); return 0; }