洛谷 P2296 尋找道路【bfs+spfa】
阿新 • • 發佈:2018-10-02
++ for %d pri ont iostream getchar ron std
反向建邊bfs出不能到t的點,然後對每個能到這些點的點打上del標記,然後spfa的時候不經過這些點即可
#include<iostream> #include<cstdio> #include<queue> #include<vector> using namespace std; const int N=200005; int n,m,h[N],cnt,s,t,dis[N]; bool v[N],f[N],d[N]; vector<int>a[N]; struct qwe { int ne,to; }e[N]; int read() { int r=0,f=1; char p=getchar(); while(p>‘9‘||p<‘0‘) { if(p==‘-‘) f=-1; p=getchar(); } while(p>=‘0‘&&p<=‘9‘) { r=r*10+p-48; p=getchar(); } return r*f; } void add(int u,int v) { cnt++; e[cnt].ne=h[u]; e[cnt].to=v; h[u]=cnt; } int main() { n=read(),m=read(); for(int i=1;i<=m;i++) { int x=read(),y=read(); if(x!=y) add(x,y),a[y].push_back(x); } s=read(),t=read(); queue<int>q; f[t]=1; q.push(t); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=0;i<a[u].size();i++) if(!f[a[u][i]]) { f[a[u][i]]=1; q.push(a[u][i]); } } for(int u=1;u<=n;u++) for(int i=h[u];i;i=e[i].ne) if(!f[e[i].to]) { d[u]=1; break; } for(int i=1;i<=n;i++) dis[i]=1e9; v[s]=1,dis[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); v[u]=0; for(int i=h[u];i;i=e[i].ne) if(!d[e[i].to]&&dis[e[i].to]>dis[u]+1) { dis[e[i].to]=dis[u]+1; if(!v[e[i].to]) { v[e[i].to]=1; q.push(e[i].to); } } } printf("%d\n",dis[t]==1e9?-1:dis[t]); return 0; }
洛谷 P2296 尋找道路【bfs+spfa】