zoukankan      html  css  js  c++  java
  • 题解 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;
    }
    
  • 相关阅读:
    Linux命令之查看cpu个数_核数_内存总数
    Python文件操作大全,随机删除文件夹内的任意文件
    Python文件操作:同一个文件进行内容替换
    异步请求Python库 grequests的应用和与requests库的响应速度的比较
    查询MySQL某字段相同值得重复数据
    /var/redis/run/redis_6379.pid exists, process is already running or crashed的解决办法
    人工智能----TensorFlow开篇简介
    Centos6.5+Python2.7 +ffmpeg+opencv2自动安装脚本
    决策统计---指标六要素
    大数据应用分类
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/13830121.html
Copyright © 2011-2022 走看看