• 题解 P2296 【寻找道路】


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

    1. 路径上的所有点的出边所指向的点都直接或间接与终点连通。
    2. 在满足条件 (1) 的情况下使路径最短。

    注意:图 GG 中可能存在重边和自环,题目保证终点没有出边。

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

    这道题,我们考虑哪些点能够到达终点,问题等价于:反向建边后,终点能到达哪些点。

    void dfs(int x){
    	h[x]=true;
    	for(auto i:E[x])
    		if(!h[i])dfs(i);
    }
    

    (E) 正是反向建边后的边集。

    (h_x=1) 就表示 (x) 号点能到终点。

    所以,我们可以判断哪些点可以走了。

    能经过的点要满足 (2) 个条件:

    1. 它自己能到达终点
    2. 它的出边所指向的点都能达到终点
    for(int i=1;i<=n;i++)
    	if(h[i]){
    		dis[i]=true;
    		for(auto j:v[i])
    			if(!h[j]){dis[i]=false;break;}
    	}
    

    这部做完了,就可以开始 (bfs) 了。

    边权全都是 (1) 自然是第 (1) 次搜到的就是最优解。

    q.push((node){s,0});
    while(q.size()){
    	node x=q.front();
    	if(x.x==t){
    		cout<<x.s;
    		return 0;
    	}
    	for(auto i:v[x.x])
    		if(dis[i]&&!vis[i]){
    			vis[i]=true;
    			q.push((node){i,x.s+1});
    		}
    	q.pop();
    }cout<<-1;
    

    还是很简单的。

    总代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    template<typename T>inline void read(T &FF){
    	T RR=1;FF=0;char CH=getchar();
    	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
    	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
    	FF*=RR;
    }
    struct node{
    	int x,s;
    };
    bool h[10010],vis[10010];
    int n,m,dis[10010],s,t;
    vector<int>v[10010];
    vector<int>E[10010];
    queue<node>q;
    void dfs(int x){
    	h[x]=true;
    	for(auto i:E[x])
    		if(!h[i])dfs(i);
    }
    int main(){
    	read(n);read(m);
    	for(int i=1;i<=m;i++){
    		int x,y;read(x);read(y);
    		v[x].push_back(y);
    		E[y].push_back(x);
    	}
    	read(s);read(t);
    	dfs(t);
    	for(int i=1;i<=n;i++)
    		if(h[i]){
    			dis[i]=true;
    			for(auto j:v[i])
    				if(!h[j]){dis[i]=false;break;}
    		}
    	q.push((node){s,0});
    	while(q.size()){
    		node x=q.front();
    		if(x.x==t){
    			cout<<x.s;
    			return 0;
    		}
    		for(auto i:v[x.x])
    			if(dis[i]&&!vis[i]){
    				vis[i]=true;
    				q.push((node){i,x.s+1});
    			}
    		q.pop();
    	}cout<<-1;
    	return 0;
    }
    
  • 相关阅读:
    tornado+websocket+mongodb实现在线视屏文字聊天
    mongoexport 导出需要授权数据库中的集合 报错 Authentication failed.
    nginx日志中添加请求的response日志
    SSE(Server-sent events)技术在web端消息推送和实时聊天中的使用
    RESTful接口设计原则和优点
    一次请求中,经过 nginx+uWSGI+flask应用程序搭建服务的执行过程
    项目中记录影响性能的缓慢数据库查询
    macos Item2 添加 Shell Integration (ftp传输)
    windows安装 阿里云的Fun工具
    windows10安装docker[含百度网盘docker安装包]
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/13830121.html
Copyright © 2020-2023  润新知