zoukankan      html  css  js  c++  java
  • 寻找道路

    问题 E: 寻找道路

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 61  解决: 9
    [提交] [状态] [讨论版] [命题人:admin]

    题目描述

    在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:
    1 .路径上的所有点的出边所指向的点都直接或间接与终点连通。
    2 .在满足条件1 的情况下使路径最短。
    注意:图G 中可能存在重边和自环,题目保证终点没有出边。
    请你输出符合条件的路径的长度。

    输入

    第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边。
    接下来的m 行每行2 个整数x 、y ,之间用一个空格隔开,表示有一条边从点x 指向点y 。

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

    0<n≤10,000,0<m≤200,000,0<x,y,s,t≤n,x≠t。

    输出

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

    样例输入

    3 2
    1 2
    2 1
    1 3
    

    样例输出

    -1
    

    提示

    如上图所示,箭头表示有向道路,圆点表示城市。起点1 与终点3 不连通,所以满足题目描述的路径不存在,故输出- 1 。 

    Solution:记录一下每个点的出度,反向建边,再从终点bfs一遍,记录终点到每个点的路径条数,如果等于出度,则满足条件1,然后用这些符合条件1的点跑最短路即可。

    #include<bits/stdc++.h>
    #define REP(i, a, b) for(int i = (a); i <= (b); ++ i)
    #define REP(j, a, b) for(int j = (a); j <= (b); ++ j)
    #define PER(i, a, b) for(int i = (a); i >= (b); -- i)
    using namespace std;
    const int maxn=3e5+666;
    template <class T>
    inline void rd(T &ret){
        char c;
        ret = 0;
        while ((c = getchar()) < '0' || c > '9');
        while (c >= '0' && c <= '9'){
            ret = ret * 10 + (c - '0'), c = getchar();
        }
    }
    int head[maxn],vis[maxn],head1[maxn],vis1[maxn],ex[maxn],tot[maxn],l,r,s,t,dis[maxn];
    struct node{
          int u,v,nx;
    }p[maxn],q[maxn];
    int n,m;
    void addedge(int x,int y){
         p[++l].u=y,p[l].v=x,p[l].nx=head[y],head[y]=l;
         q[++r].u=x,q[r].v=y,q[r].nx=head1[x],head1[x]=r;
    }
    queue<int>qu;
    void bfs(){
        qu.push(t);
        vis[t]=1;
        while(qu.size()){
            int cur=qu.front();
            qu.pop();
            for(int i=head[cur];i;i=p[i].nx){
                int to=p[i].v;
                tot[to]++;
                if(!vis[to]){
                    qu.push(to);
                    vis[to]=1;
                }
            }
        }
    }
    void spfa(){
         qu.push(s);
         REP(i,1,n)dis[i]=0x3f3f3f3f;
         dis[s]=0,vis1[s]=1;
         while(qu.size()){
              int cur=qu.front();
              qu.pop();
              vis1[cur]=0;
              for(int i=head1[cur];i;i=q[i].nx){
                   int to=q[i].v;
                   if(dis[to]>dis[cur]+1&&ex[to]==tot[to]){
                        dis[to]=dis[cur]+1;
                        if(!vis1[to]){
                            vis1[to]=1,qu.push(to);
                        }
                   }
              }
         }
    }
    int main(){
        rd(n),rd(m);
        REP(i,1,m){
           int a,b;
           rd(a),rd(b),ex[a]++;
           addedge(a,b);
        }
        rd(s),rd(t);
        bfs();
        spfa();
        if(dis[t]==0x3f3f3f3f)cout<<-1<<endl;
        else cout<<dis[t]<<endl;
        return 0;
    }
  • 相关阅读:
    台州 OJ 3847 Mowing the Lawn 线性DP 单调队列
    洛谷 OJ P1417 烹调方案 01背包
    快速幂取模
    台州 OJ 2649 More is better 并查集
    UVa 1640
    UVa 11971
    UVa 10900
    UVa 11346
    UVa 10288
    UVa 1639
  • 原文地址:https://www.cnblogs.com/czy-power/p/10412533.html
Copyright © 2011-2022 走看看