zoukankan      html  css  js  c++  java
  • NOIP2014D2T2寻找道路(Spfa)

    洛谷传送门

    这道题可以把边都反着存一遍,从终点开始深搜,然后把到不了的点 和它们所指向的点都去掉。

    最后在剩余的点里跑一遍spfa就可以了。

    ——代码

    #include <cstdio>
    #include <cstring>
    #include <queue>
    
    const int maxn = 100001;
    int n, m, s, t, cnt1, cnt2;
    int dis[maxn];
    int next1[4 * maxn], to1[4 * maxn], head1[4 * maxn], 
        next2[4 * maxn], to2[4 * maxn], head2[4 * maxn];
    bool vis[maxn], b[maxn], f[maxn], flag;
    
    inline void add1(int x, int y)
    {
        to1[cnt1] = y;
        next1[cnt1] = head1[x];
        head1[x] = cnt1++;
    }
    
    inline void add2(int x, int y)
    {
        to2[cnt2] = y;
        next2[cnt2] = head2[x];
        head2[x] = cnt2++;
    }
    
    inline void dfs(int u)
    {
        int i, v;
        if(u == s) flag = 1;
        vis[u] = 1;
        for(i = head2[u]; i != -1; i = next2[i])
        {
            v = to2[i];
            if(!vis[v]) dfs(v);
        }
    }
    
    inline void spfa(int u)
    {
        int i, j;
        std::queue <int> q;
        q.push(u);
        f[u] = 1;
        dis[u] = 0;
        while(!q.empty())
        {
            i = q.front();
            q.pop();
            f[i] = 0;
            for(j = head1[i]; j != -1; j = next1[j])
             if(!b[i] && !b[to1[j]] && dis[to1[j]] > dis[i] + 1)
             {
                 dis[to1[j]] = dis[i] + 1;
                 if(!f[to1[j]])
                 {
                     f[to1[j]] = 1;
                     q.push(to1[j]);
                 }
             }
        }
    }
    
    int main()
    {
        int i, j, x, y;
        memset(head1, -1, sizeof(head1));
        memset(head2, -1, sizeof(head2));
        memset(dis, 127 / 3, sizeof(dis));
        scanf("%d %d", &n, &m);
        for(i = 1; i <= m; i++)
        {
            scanf("%d %d", &x, &y);
            add1(x, y);
            add2(y, x);
        }
        scanf("%d %d", &s, &t);
        dfs(t);
        if(!flag)
        {
            printf("-1");
            return 0;
        }
        for(i = 1; i <= n; i++)
         if(!vis[i])
         {
             b[i] = 1;
             for(j = head2[i]; j != -1; j = next2[j]) b[to2[j]] = 1;
         }
        spfa(s);
        printf("%d", dis[t]);
        return 0;
    }
    View Code
  • 相关阅读:
    #leetcode刷题之路32-最长有效括号
    #leetcode刷题之路31-下一个排列
    数据结构第一节 递归
    数据结构 第一节
    java基础 抽象类与接口
    Spring1
    java基础3。定义类
    java基础2。基本数据类型
    java基础1。面向对象
    丑数
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6670761.html
Copyright © 2011-2022 走看看