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";
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366402.html