zoukankan      html  css  js  c++  java
  • 题解 P2296 【寻找道路】

    写在前面:

    在窝的博客食用口感更佳

    这应该是2019CSP之前写的最后一篇题解吧

    关于码风等细节说明:

    • 用了链式前向星

    • 码风奇异,是蒟蒻风的

    • \(n^2\)能过,没加堆优化


    思路:

    • 反向建边,从终点跑一次dijkstra

    • inf值的删掉自己和出边是到自己的点

    • 正常的建边从起点跑一次dijkstra


    详细解析:

    就是因为条件一导致我不得套板子!我要把条件一吞掉!

    怎么吞呢?我们只保留那些所有出边所指向的点都直接或间接与终点连通的点即可

    我们可以反向建图,从终点出发跑一边dijkstra

    这样所有距离终点为inf的就无法到达终点,删掉它们!

    (开个bool数组flag,将它们的flag值设为1)

    把出边到距离终点是inf的点删掉,仍然使用flag数组可能会多删一些点怎么办?

    用bool数组tmp存储一开始的flag数组的值,更新全部更新到flag数组

    for(int i=1;i<=n;i++)
    	if(dist[i]==inf)
    		tmp[i]=flag[i]=1;
    for(int i=1;i<=m;i++)
    	if(tmp[V[i]]) flag[U[i]]=1;
    

    接下来就只要在剩下的图上愉快地跑dijkstra了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define inf 0x3f3f3f3f
    int n,m,cnt,s,t;
    int hd[10005],dist[10005];
    bool vis[100005],flag[100005],tmp[100005];
    //vis[i]:i点是否已被确定最短路,flag[i]:i点是否被删 
    int U[200005],V[200005],to[200005],nex[200005];
    void add(int u,int v){
    	to[++cnt]=v;
    	nex[cnt]=hd[u];
    	hd[u]=cnt;
    }
    void dijkstra(int from){
    	memset(dist,0x3f,sizeof(dist));
    	int cur=from;
    	dist[from]=0;
    	while(!vis[cur]){
    		vis[cur]=1;
    		for(int i=hd[cur];i;i=nex[i]){
    			int v=to[i];
    			if(dist[v]>dist[cur]+1)
    				dist[v]=dist[cur]+1;
    		}
    		int minn=inf;
    		for(int i=1;i<=n;i++){
    			if(!flag[i]&&!vis[i]){
    				if(minn>dist[i]){
    					minn=dist[i];
    					cur=i;
    				}
    			}
    		}
    	}
    }
    int main() {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d",&U[i],&V[i]);
    		add(V[i],U[i]);
    	}
    	scanf("%d%d",&s,&t);
    	dijkstra(t);
    	for(int i=1;i<=n;i++)
    		if(dist[i]==inf)
    			tmp[i]=flag[i]=1;
    	cnt=0;
    	memset(vis,0,sizeof(vis));
    	memset(hd,0,sizeof(hd));
    	memset(to,0,sizeof(to));
    	memset(nex,0,sizeof(nex));
    	for(int i=1;i<=m;i++)
    		if(tmp[V[i]]) flag[U[i]]=1;
    	for(int i=1;i<=m;i++)
    		if(!flag[U[i]]&&!flag[V[i]])
    			add(U[i],V[i]);
    	dijkstra(s);
    	if(dist[t]==inf) printf("-1\n");
    	else printf("%d\n",dist[t]);
    	return 0;
    }
    
    qaqaq
  • 相关阅读:
    vs2017中信号与槽连接
    生成格雷码
    结构光三维测量技术
    格雷码生成算法
    结构光三维重建
    Qt之CMake和MinGW编译OpenCV
    qt+opencv编译环境的配置
    vs2017+opencv配置参考链接
    2019-3-25多线程的同步与互斥(互斥锁、条件变量、读写锁、自旋锁、信号量)
    2019-3-22c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字
  • 原文地址:https://www.cnblogs.com/zdsrs060330/p/13095059.html
Copyright © 2011-2022 走看看