zoukankan      html  css  js  c++  java
  • NOIP2014提高组-day2-2——寻找道路(。。。。这算什么题呢。。?最短路?)

    在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:
    1.路径上的所有点的出边所指向的点都直接或间接与终点连通。 2.在满足条件1的情况下使路径最短。
    注意:图G中可能存在重边和自环,题目保证终点没有出边。
    请你输出符合条件的路径的长度。
    输入
    第一行有两个用一个空格隔开的整数n和m,表示图有n个点和m条边。    接下来的m行每行2个整数x、y,之间用一个空格隔开,表示有一条边从点x指向点y。
    最后一行有两个用一个空格隔开的整数s、t,表示起点为s,终点为t。
    输出
    输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出- 1。
    样例输入
    3 2
    1 2
    2 1
    1 3
    road.in
    6 6
    1 2
    1 3
    2 6
    2 5
    4 5
    3 4
    1 5
    样例输出
    -1
    样例2:
    road.out
    3

    考虑到所有点的出边都必须和终点相连

    那我们在建有向图的时候也建一个反向图

    那我们可以先从终点沿反向图dfs一次,把所有能走到的点标出来

    然后从起点开始跑最短路

    每次对于一个新的点,我们先枚举其所有出去的点,如果有的点没有被标出来

    那么这个点显然是不能走

    continue就可以了

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    const int N=10005;
    const int M=200005;
    int n,m,adj[N],nxt[M],to[M],dis[N],head[N],go[M],nec[M],str,des,cnt,tot;
    bool vis[N],pas[N];
    inline void addedge(int u,int v){
        nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
        nec[++tot]=head[v],head[v]=tot,go[tot]=u;
    }
    inline void dfs(int u){
        for(int e=head[u];e;e=nec[e]){
            int v=go[e];
            if(pas[v])continue;
            pas[v]=true;
            dfs(v);
        }
    }
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
    inline void dijkstra(){
        memset(dis,127,sizeof(dis));
        q.push(make_pair(0,str));dis[str]=0;
        while(!q.empty()){
            int u=q.top().second;q.pop();
            if(vis[u])continue;vis[u]=true;
            bool flag=true;
            for(int e=adj[u];e;e=nxt[e]){
                int v=to[e];
                if(!pas[v])flag=false;
            }
            if(!flag)continue;
            for(int e=adj[u];e;e=nxt[e]){
                int v=to[e];
                if(dis[u]+1<dis[v]){
                    dis[v]=dis[u]+1;
                    q.push(make_pair(dis[v],v));
                }
            }
        }
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            addedge(u,v);
        }
        str=read(),des=read();pas[des]=1;
        dfs(des);
        dijkstra();
        if(dis[des]<1000000000)
        cout<<dis[des];
        else cout<<"-1";
    }
    
  • 相关阅读:
    本地图文直接复制到文本编辑器中
    本地图文直接复制到富文本编辑器中
    本地多张图片直接复制到富文本编辑器中
    能粘贴Word 内容(含图片)的富文本编辑器
    能粘贴Word 内容(含图片)的文本编辑器
    js+WebUploader分片上传大文件
    js+web分片上传大文件
    js+前端分片上传大文件
    Java学习——方法中传递参数分简单类型与复杂类型(引用类型)
    线段树练习
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366402.html
Copyright © 2011-2022 走看看