luogu2296 [NOIp2014]寻找道路 (bfs)
反着建边,从T bfs找合法的点,然后再正着bfs一下求最短路就行了
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define lowb(x) ((x)&(-(x))) 4 #define REP(i,n0,n) for(i=n0;i<=n;i++) 5 #define PER(i,n0,n) for(i=n;i>=n0;i--) 6 #define MAX(a,b) ((a>b)?a:b) 7 #define MIN(a,b) ((a<b)?a:b) 8 #define CLR(a,x) memset(a,x,sizeof(a)) 9 #define rei register int 10 using namespace std; 11 typedef long long ll; 12 const int maxn=10010,maxm=200020; 13 14 inline ll rd(){ 15 ll x=0;char c=getchar();int neg=1; 16 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 17 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 18 return x*neg; 19 } 20 21 int N,M,S,T; 22 int eg[maxm*2][2],egh[maxn],ect; 23 int neg[maxm*2][2],negh[maxn],nect,dis[maxn]; 24 bool vis[maxn],used[maxn],flag[maxn]; 25 queue<int> q; 26 27 inline void adeg(int a,int b){ 28 eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect; 29 } 30 inline void nadeg(int a,int b){ 31 neg[++nect][0]=b;neg[nect][1]=negh[a];negh[a]=nect; 32 } 33 34 void bfs1(){ 35 q.push(T); 36 while(!q.empty()){ 37 int p=q.front();q.pop(); 38 if(vis[p]) continue; 39 vis[p]=1; 40 for(int i=negh[p];i;i=neg[i][1]){ 41 int b=neg[i][0]; 42 if(!vis[b]) q.push(b); 43 } 44 } 45 for(int i=1;i<=N;i++){ 46 bool b=1; 47 for(int j=egh[i];j;j=eg[j][1]){ 48 if(!vis[eg[j][0]]) b=0; 49 }used[i]=b; 50 // printf("!%d %d %d\n",i,used[i],vis[i]); 51 } 52 } 53 54 int bfs2(){ 55 if(used[S]) q.push(S); 56 dis[S]=0; flag[S]=1; 57 while(!q.empty()){ 58 int p=q.front();q.pop(); 59 if(p==T) return dis[p]; 60 for(int i=egh[p];i;i=eg[i][1]){ 61 if(!used[eg[i][0]]) continue; 62 if(!flag[eg[i][0]]) dis[eg[i][0]]=dis[p]+1,q.push(eg[i][0]),flag[eg[i][0]]=1; 63 } 64 }return -1; 65 } 66 67 int main(){ 68 rei i,j,k; 69 N=rd(),M=rd(); 70 for(i=1;i<=M;i++){ 71 int a=rd(),b=rd(); 72 adeg(a,b);nadeg(b,a); 73 }S=rd(),T=rd(); 74 bfs1(); 75 printf("%d\n",bfs2()); 76 77 return 0; 78 }