洛谷P2296

来源:互联网 发布:淘宝助理点打印没反应 编辑:程序博客网 时间:2024/05/22 01:38

点击看题

这题……无脑BFS(我还脑残地打了SPFA,看洛谷上大神们用的都是两次BFS……)

首先在反图上跑一遍BFS看看哪些点不符合条件。题目说路径上的点出边指向的点都与终点连通,所以我们将整张图反过来,看看有哪些点从终点出发不可达,然后在图上把原图中指向这些不可达点的点删掉就可以了。

然后,无脑最短路SPFA……(Orz各路大神用BFS……算了,当练一下模板)

代码:

#include<iostream>#include<cstdio>#include<cmath>#include<queue>#include<algorithm>#include<cstring>#define repu(i,l,r) for(int i=l;i<=r;i++)#define repd(i,r,l) for(int i=r;i>=l;i--)#define M 225000#define N 15000using namespace std;struct e{int en,next;}edge[M],redge[M];int n,m,s,t,x,y,head[M],rhead[M],cnt,rcnt,able[N]={0},legal[N]={0},d[N],vis[N]={0};queue<int> q;void addedge(int x,int y){cnt++;edge[cnt].en=y;edge[cnt].next=head[x];head[x]=cnt;}void addredge(int y,int x){rcnt++;redge[rcnt].en=x;redge[rcnt].next=rhead[y];rhead[y]=rcnt;}int read(){char ch=getchar();int ret=0;while (ch>'9'||ch<'0') ch=getchar();while (ch<='9'&&ch>='0'){ret=ret*10+ch-'0';ch=getchar();}return ret;}int main(){n=read(),m=read();repu(i,1,m){x=read(),y=read();addedge(x,y);addredge(y,x);}s=read(),t=read();q.push(t);able[t]=1;while(!q.empty()){x=q.front();q.pop();for(int e=rhead[x];e;e=redge[e].next){y=redge[e].en;if (!able[y]){able[y]=1;q.push(y);}}}repu(i,1,n){if (!able[i]) continue;else{int ability=1;for(int e=head[i];e;e=edge[e].next){y=edge[e].en;if (!able[y]){ability=0;break;}}legal[i]=ability;}}if (!legal[s]) {printf("-1");return 0;}repu(i,1,n)d[i]=M;d[s]=0;vis[s]=1;memset(vis,0,sizeof(vis));queue<int> qs;qs.push(s);while (!qs.empty()){x=qs.front();qs.pop();for(int e=head[x];e;e=edge[e].next){int to=edge[e].en;if (!legal[to]) continue;if (d[to]>d[x]+1){d[to]=d[x]+1;if (!vis[to]){vis[to]=1;qs.push(to);}}    }    vis[x]=0;}if (d[t]==M) printf("-1");else printf("%d",d[t]);return 0;}




0 0
原创粉丝点击