• 洛谷P2296寻找道路


    传送门啦

    题目中有一个条件是路径上的所有点的出边所指向的点都直接或间接与终点连通。

    所以我们要先判断能否走这一个点, $ bfs $ 类似 $ spfa $ 的一个判断,打上标记。

    在这我反向建图,最后跑最短路的时候就从终点跑到起点,也是一样的。在最短路中加上一个判断就好了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    #define re register
    using namespace std;
    const int maxn = 10005;
    const int maxm = 200005;
    
    inline int read(){
    	char ch = getchar();
    	int f = 1 , x = 0;
    	while(ch > '9' || ch < '0' ) { if(ch == '-')f = -1;ch = getchar();}
    	while(ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3 ) + ch - '0';ch = getchar();}
    	return x * f;
    }
    
    int n , m , x , y , s , t ;
    int head[maxn] , tot ;
    bool vis[maxm] , ok[maxm] ;
    
    struct Edge{
    	int from,to,next,val;
    }edge[maxm << 1];
    
    struct Node {
    	int u , d;
    	bool operator < (const Node &f) const {
    		return d > f.d;
    	}
    };
    
    inline void add(int u , int v , int w){
    	edge[++tot].from = u ;
    	edge[tot].to = v ;
    	edge[tot].val = w;
    	edge[tot].next = head[u];
    	head[u] = tot ;
    }
    
    inline void bfs(int t){
    	queue<int>  que;
    	memset(vis , false , sizeof(vis) );
    	que.push(t);
    	vis[t] = true;
    	ok[t] = true;
    	while( !que.empty() ){
    		int cur = que.front();
    		que.pop();
    		for(re int i = head[cur] ; i ; i = edge[i].next){
    			int v = edge[i].to ;
    			if(vis[v] == false){
    				ok[v] = true ;
    				vis[v] = true;
    				que.push(v);
    			}
    		}
    	}
    }
    
    int dis[maxn];
    inline void dijk(int t){
    	for(re int i = 1 ;i <= n ; ++i) dis[i] = 1e9;
    	priority_queue<Node> q;
    	dis[t] = 0;
    	q.push( (Node) {t , dis[t]});
    	while( ! q.empty() ){
    		Node cur = q.top();
    		q.pop() ;
    		int d = cur.d , u = cur.u ;
    		if(d != dis[u]) continue;
    		for(re int i = head[u] ; i; i = edge[i].next){
    			int v = edge[i].to;
    			if(ok[v])  continue;
    			if(dis[v] > dis[u] + edge[i].val){
    				dis[v] = dis[u] + edge[i].val;
    				q.push( (Node) {v , dis[v]} );
    			}
    		}
    	}
    }
    
    int main(){
    	n = read(); m = read();
    	for(re int i = 1 ; i <= m ; ++i) {
    		x = read();  y = read(); 
    		add(y , x , 1);
    	}
    	s = read() ; t = read() ;
    	bfs(t) ;
    	for(re int i = 1 ; i <= n ; ++i){
    		vis[i] = ok[i];
    	}
    	memset(ok , false , sizeof(ok));
    	for(int i = 1 ; i <= n ; ++i){
    		if(!vis[i]) {
    			for(re int j = head[i] ; j ; j = edge[j].next) {
    				int v = edge[j].to;
    				ok[v] = true; 
    			}
    		}
    	}
    	dijk(t) ;
    	if(dis[s] != 1e9)  printf("%d
    ",dis[s]);
    	else printf("-1
    ");
    	return 0;
    }
    
  • 相关阅读:
    Java中的匿名对象、内部类、包、代码块
    Java中的final和static关键字
    Java中的this与super关键字
    Java中的构造方法
    Java中的多态
    Vue+Element中Table懒加载,新增、删除操作后手动更新
    JQ取消hover事件
    github.com访问慢解决
    vue cli3 子目录问题
    右键事件 contextmenu
  • 原文地址:https://www.cnblogs.com/Stephen-F/p/9925574.html
Copyright © 2020-2023  润新知