zoukankan      html  css  js  c++  java
  • P2296 寻找道路(dfs+spfa)

    洛谷 P2296 寻找道路

    题目描述

    在有向图 GG 中,每条边的长度均为 11,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:

    路径上的所有点的出边所指向的点都直接或间接与终点连通。
    在满足条件 1 1的情况下使路径最短。
    注意:图 GG 中可能存在重边和自环,题目保证终点没有出边。

    请你输出符合条件的路径的长度。

    输入输出格式
    输入格式:

    第一行有两个用一个空格隔开的整数 nn 和 mm,表示图有 nn 个点和 mm 条边。

    接下来的 mm 行每行 22 个整数 x,yx,y,之间用一个空格隔开,表示有一条边从点 xx 指向点yy。

    最后一行有两个用一个空格隔开的整数 s, ts,t,表示起点为 ss,终点为 tt。

    输出格式:

    输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出-1−1。

    输入输出样例
    输入样例#1:

    3 2
    1 2
    2 1
    1 3

    输出样例#1:

    -1
    输入样例#2:
    6 6
    1 2
    1 3
    2 6
    2 5
    4 5
    3 4
    1 5
    输出样例#2:
    3
    分析:题目要找出路径上的所有点的出边所指向的点都直接或间接与终点连通。也就是说当前点有一条边的出边最终没有连到终点,那么这个点就是不合条件的,标记不能通过这个点进行松弛。如样例2

    因为2的一条出边指向6,而6最终没有指向终点5,所以与2有关的边不能作为松弛的点

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e6+10;
    const int inf = 0x3f3f3f3f;
    struct node{
        int v, w, nxt;
    }edge[N];
    int n, m, cnt, st, ed;
    int fir[N], x[N], y[N], dis[N];
    bool vis[N], book[N], book1[N];
    inline void add(int u, int v, int w){
        edge[cnt] = (node){v, w, fir[u]};
        fir[u] = cnt++;
    }
    inline void dfs(int u){
        book[u] = true;
        for(int i = fir[u]; i; i = edge[i].nxt){
            int v = edge[i].v;
            if(!book[v])
                dfs(v);
        }
    }
    inline int spfa(int st){
        memset(vis, false, sizeof(vis));
        vis[st] = true;
        for(int  i = 1; i <= n; i++){
            dis[i] = inf;
        }
        dis[st] = 0;
        queue<int> Q;
        Q.push(st);
        while(!Q.empty()){
            int u = Q.front();
            Q.pop();
            vis[u] = true;
            for(int i = fir[u]; i; i = edge[i].nxt){
                int v = edge[i].v;
                if(book1[v]){
                    continue;
                }
                if(dis[v] > dis[u] + edge[i].w){
                    dis[v] = dis[u] + edge[i].w;
                    if(!vis[v]){
                        vis[v] = false;
                        Q.push(v);
                    }
                }
            }
        }
        return dis[ed];
    }
    int main(){
        #ifdef ONLINE_JUDGE
        #else
            freopen("in.txt", "r", stdin);
        #endif // ONLINE_JUDGE
    
        while(~scanf("%d%d", &n, &m)){
            cnt = 1;
            memset(fir, 0, sizeof(fir));
            memset(book, 0, sizeof(book));
            for(int i = 0; i < m; i++){
                scanf("%d%d", &x[i], &y[i]);
                add(y[i], x[i], 1);
            }
            scanf("%d%d", &st, &ed);
            dfs(ed);
            memset(fir, 0, sizeof(fir));
            for(int i = 0; i < m; i++){
                add(x[i], y[i], 1);
            }
            for(int i = 1; i <= n; i++){
                book1[i] = false;
                for(int j = fir[i]; j; j = edge[j].nxt){
                    int v = edge[j].v;
                    if(!book[v]){
                        book1[i] = true;
                        break;
                    }
                }
            }
            int ans = spfa(st);
            if(ans == inf)
                printf("-1
    ");
            else
                printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    IIS日志分析
    Linux 管理软件
    lodop打印收费小票
    文件上传,服务端压缩文件方法,重点是png与gif图片的压缩,保证了透明度与动画
    设置表格隔行变色,以及鼠标悬浮变色效果
    地址下拉框,需要js级联js
    下拉框多级联动辅助js,优化您的下拉框
    给下拉框加上可输入查询特性,包括中文与拼音首字母
    判断浏览器客户端是不是移动客户端
    url重定向或者重写
  • 原文地址:https://www.cnblogs.com/kun-/p/10108190.html
Copyright © 2011-2022 走看看