• 寻找道路


    https://www.luogu.org/problemnew/show/P2296

    题目很简单,但竟然没一遍A,基础不行啊...

    做法很显然,反向建边看哪些点和终点连通,再看哪些点合法能被走,最后正向dfs一次就行

    然而没一遍A,是因为bfs的时候vis和ok的处理有问题(看代码

    应该在找到节点之后,立即对其进行处理。而不应该在弹出队列的时候对节点进行处理

    一个教训吧

    0.5h

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<iostream>
    using namespace std;
    #define O(x) cout << #x << " " << x << endl;
    #define B cout << "breakpoint" << endl;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch  = getchar();
        }
        return ans * op;
    }
    const int maxn = 1e5 + 5;
    struct node
    {
        int to,next,cost;
    }e[maxn << 1],rev[maxn << 1];
    int fir[maxn],alloc,r_fir[maxn],r_alloc;
    void adde(int u,int v)
    {
        e[++alloc].next = fir[u];
        fir[u] = alloc;
        e[alloc].to = v;
        swap(u,v);
        rev[++r_alloc].next = r_fir[u];
        r_fir[u] = r_alloc;
        rev[r_alloc].to = v;
    }
    bool ok[maxn],vis[maxn],con[maxn];
    int n,m,s,t;
    void mark_rev()
    {
        queue<int> q;
        q.push(t);
        vis[t] = 1,ok[t] = 1;
        memset(vis,0,sizeof(vis));
        while(q.size())
        {
            int u = q.front();
            q.pop();
            for(int i = r_fir[u];i;i = rev[i].next)
            {
                int v = rev[i].to;
                if(vis[v]) continue;
                vis[v] = ok[v] = 1;
                q.push(v);
            }
        }
        for(int u = 1;u <= n;u++)
        {
            bool flag = 0;
            for(int i = fir[u];i;i = e[i].next)
            {
                int v = e[i].to;
                if(ok[v] == 0) { con[u] = 0; flag = 1; break; }
            }
            if(flag == 0) con[u] = 1;
        }
    }
    int dis[maxn];
    void solve()
    {
        memset(vis,0,sizeof(vis));
        queue<int> q;
        q.push(s);
        dis[s] = 0;
        vis[s] = 1;
        while(q.size())
        {
            int u = q.front();
            q.pop();
            for(int i = fir[u];i;i = e[i].next)
            {
                int v = e[i].to;
                if(vis[v] || con[v] == 0) continue;            
                dis[v] = dis[u] + 1;
                vis[v] = 1;
                q.push(v);
            }
        }
        if(dis[t] == 0) printf("-1");
        else printf("%d",dis[t]);
    }    
    int main()
    {
        n = read(),m = read();
        for(int i = 1;i <= m;i++)
        {
            int u = read(),v = read();
            if(u == v) continue;
            adde(u,v);
        }
        s = read(),t = read();
        mark_rev();
        solve();
    }
  • 相关阅读:
    数据存储 twisted
    数据存储 mongodb
    数据存储 redis
    数据存储 txt
    同时使用有线内网与无线外网
    使用xshell从服务器下载文件
    everything使用技巧
    【吴恩达机器学习】第8章 正则化
    python文件重命名
    【统计学习】 第5章 决策树
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/10697570.html
Copyright © 2020-2023  润新知