Noip 2014 提高组 寻找道路

来源:互联网 发布:mysql workbanch 编辑:程序博客网 时间:2024/06/09 23:22

分析

反向bfs找出可行的点+正向SPFA找最短路。


代码

#include<cstdio>using namespace std; #define N 10010#define M 200010#define inf 1000000000#define to e[i].vint head[M],headx[M],dist[N],vis[N],ok[N],q[N],Ok[N];int id,idx,l,r,n,m,s,t;struct node{int w,v,next;}e[M],ex[M];int max(int a,int b) {return a>b? a:b;}int min(int a,int b) {return a>b? b:a;}void swap(int &a,int &b) {int t=a;a=b;b=t;}void add(int u,int v,int w) {e[id].v=v; e[id].w=w; e[id].next=head[u]; head[u]=id++;}void addx(int u,int v,int w) {ex[idx].v=v; ex[idx].w=w; ex[idx].next=headx[u]; headx[u]=idx++;}int read(){    int x=0,f=1;char ch=getchar();    for (;ch>'9'||ch<'0';ch=getchar()) if (ch=='-') f=-1;    for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';    return x*f;}void spfa(){for (int i=1;i<=n;i++) dist[i]=inf,vis[i]=0;q[l=1]=s; dist[s]=0; r=1; vis[s]=1;for (;l<=r;){int u=q[l++]; vis[u]=0;for (int i=head[u];i;i=e[i].next)if (Ok[to] && dist[u]+e[i].w<dist[to]){dist[to]=dist[u]+e[i].w;if (!vis[to]){q[++r]=to;vis[to]=1;}                     }}}int main(){n=read(); m=read(); id=1; idx=1;for (int i=1;i<=m;i++){int u=read(),v=read();add(u,v,1); addx(v,u,1);}s=read(); t=read();for (int i=1;i<=n;i++) ok[i]=0;q[l=1]=t; r=1; ok[t]=1; for (;l<=r;){int u=q[l++]; for (int i=headx[u];i;i=ex[i].next)if (!ok[ex[i].v]){q[++r]=ex[i].v;ok[ex[i].v]=1;}}for (int i=1;i<=n;i++) Ok[i]=1;for (int u=1;u<=n;u++){if (!ok[u]) {Ok[u]=0;continue;}for (int i=head[u];i;i=e[i].next)if (!ok[to]) {Ok[u]=0; break;}}spfa();if (dist[t]==inf) printf("-1"); else printf("%d",dist[t]);return 0;}


原创粉丝点击