UOJ 19 [NOIP2014]寻找道路

来源:互联网 发布:智能网络平板电视 编辑:程序博客网 时间:2024/06/06 02:58

图的遍历+最短路。

第一眼看,好难,不会做。

仔细一看,发现只要一次反向边BFS把不合题意的点全部丢掉就可以直接跑最短路了- -

顺利打完之后被hack成97分,原因是没有判断起点直接不可取的情况。改后AC。

#include<cstdio>#include<queue>#include<cstring>#define N 10005#define M 200005using namespace std;struct edge{int next,to;}e[M<<1];int cnt=0, last[2][N], n, m, s, t, d[N];bool vis[N], ban[N], inq[N];void add(int i, int a, int b){    e[++cnt]=(edge){last[i][a],b};    last[i][a]=cnt; }void bfs(int beg){    queue<int> q;    q.push(beg);    vis[beg]=1;    while(!q.empty())    {        int x=q.front();        q.pop();        for(int i = last[1][x]; i; i=e[i].next)        {            int y=e[i].to;            if(vis[y])continue;            vis[y]=1;            q.push(y);        }    }}void solve(){    for(int i = 1; i <= n; i++)        if(!vis[i])            for(int j = last[1][i]; j; j=e[j].next)                ban[e[j].to]=1;}int SPFA(int beg, int end){    if(ban[beg])return -1;    memset(d,63,sizeof(d));    queue<int> q;    q.push(beg);    d[beg]=0;    while(!q.empty())    {        int x=q.front();        q.pop();        inq[x]=0;        for(int i = last[0][x]; i; i=e[i].next)        {            int y=e[i].to;            if(ban[y] || d[x]+1>=d[y])continue;            d[y]=d[x]+1;            if(!inq[y])            {                inq[y]=1;                q.push(y);            }        }    }    return d[end];}int main(){    scanf("%d%d",&n,&m);    for(int a, b, i = 1; i <= m; i++)    {        scanf("%d%d",&a,&b);        add(0,a,b);        add(1,b,a);    }    scanf("%d%d",&s,&t);    bfs(t);    solve();    int ans = SPFA(s, t);    printf("%d\n",ans>N?-1:ans);} 
1 0
原创粉丝点击