P2296 寻找道路

好吧,我又完全不会了。。。


这道题有两个限制条件:

  1. 路径上的所有点的出边所指向的点直接或间接与终点连通。

  2. 在满足条件 1 的情况下使路径最短。

对于第一个条件,我们可以寻找与终点不连通的那些点。

如果有点的出边是不连通的点的话,那么这个点就一定不在路径上。

对于第二个条件,直接跑最短路。

有一个坑点

在筛选哪些点可以选择的时候,操作有后效性。

注意!!!!!!!!!!把vis数组置为false之前一定要备份一份vis数组!!!!!!!

因为有后效性!!!!!

如果一个点一开始被标记,它通过一个不和终点连接的点删除了,那么有可能过一会被当作一开始就没有标记的点!

没注意这个点的话是20分,直接炸了。

代码:

#include<cstdio>
#include<cstring>
#include<queue>

const int maxn = 10005, maxm = 200005;
struct Edges
{
    int next, to;
} e[maxm];
int head[maxn], tot;
int n, m, s, t;
bool vis[maxn], backup[maxn];
struct Nodes
{
    int u, dir;
};

int read()
{
    int ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0')
    {
        if(ch == '-') s = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        ans = ans * 10 + ch - '0';
        ch = getchar();
    }
    return s * ans;
}
void link(int u, int v)
{
    e[++tot] = (Edges){head[u], v};
    head[u] = tot;
}
void bfs1()
{
    std::queue<int> q;
    q.push(t); vis[t] = true;
    while(!q.empty())
    {
        int u = q.front(); q.pop();
        for(int i = head[u]; i; i = e[i].next)
        {
            int v = e[i].to;
            if(!vis[v])
            {
                q.push(v); vis[v] = true;
            }
        }
    }
}
int bfs2()
{
    std::queue<Nodes> q;
    q.push((Nodes){t, 0});
    while(!q.empty())
    {
        Nodes x = q.front(); q.pop();
        if(x.u == s) return x.dir;
        for(int i = head[x.u]; i; i = e[i].next)
        {
            int v = e[i].to;
            if(vis[v])
            {
                q.push((Nodes){v, x.dir + 1});
            }
        }
    }
    return -1;
}
int main()
{
    n = read(), m = read();
    while(m--)
    {
        int u = read(), v = read();
        link(v, u);
    }
    s = read(), t = read();
    bfs1();
    memcpy(backup, vis, sizeof(backup));
    for(int j = 1; j <= n; j++)
    {
        if(!backup[j])
        {
            for(int i = head[j]; i; i = e[i].next)
            {
                int v = e[i].to;
                vis[v] = false;
            }
        }
    }
    printf("%d\n", bfs2());
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Garen-Wang/p/9337159.html