zoukankan      html  css  js  c++  java
  • C++ P4568 [JLOI2011]飞行路线 ---- Dijkstra+分层图

    题目地址:https://www.luogu.org/problemnew/show/P4568

    Dijkstra:https://blog.csdn.net/u012972031/article/details/83476580


    分层图是什么

    顾名思义,所谓的"分层图",就是分层的图。

    分层图的用处

    在某些情况下,需要在普通的图上算法的基础上增加一些特殊功能,如:某些边权值为0,且这些边是由我们动态生成的。这时候裸的Dijkstra显然无法胜任,那么我们就可以考虑一下使用分层图了。

    分层图的实现方法

    • 第一种:同时建多个图,并将这些图连起来,就像链表一样。
    • 第二种:使用一个二维的dis[]数组,第二个下标储存层数。(这种方法比较快)

    分层图的具体实现:

    • 第一种:
    • 第二种:
    • 使用DP方式(用于优化性能),在此不再出示图片

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    int s,k,cnt=0,dis[1000010*20],head[1000010*20];
    struct Edge{
    	int v,w,next;
    }e[500005*30];
    struct Node{
    	int u,d;
    	bool const operator <(const Node& a)const{
    		return d>a.d;
    	}
    };
    void addEdge(int u,int v,int w){
    	e[++cnt].v=v;
    	e[cnt].w=w;
    	e[cnt].next=head[u];
    	head[u]=cnt;
    }
    void dijkstra(){
    	dis[s]=0;
    	priority_queue<Node> q;
    	q.push((Node){s,0});
    	while(!q.empty()){
    		Node n=q.top();q.pop();
    		int u=n.u,d=n.d;
    		if(d!=dis[u])continue;
    		for(int i=head[u];i;i=e[i].next){
    			int v=e[i].v,w=e[i].w;
    			if(dis[u]+w<dis[v]){
    				dis[v]=dis[u]+w;
    				q.push((Node){v,dis[v]});
    			}
    		}
    	}
    }
    int main(){
    	int n,m;
    	scanf("%d%d%d",&n,&m,&k);
    	int t;
    	scanf("%d%d",&s,&t);
    	for(int i=1;i<=m;i++){
    		int a,b,c;
    		scanf("%d%d%d",&a,&b,&c);
    		for(int i=0;i<=k;i++){
    			int ta=i*n+a,tb=i*n+b;//tb往前连,ta往后连 
    			addEdge(ta,tb,c); 
    			addEdge(tb,ta,c);
    			if(i!=k){//如果不是最后一个图 
    				addEdge(tb,ta+n,0);//tb往前连 
    				addEdge(ta,tb+n,0);//ta往后连  
    			}
    		}//普通建图
    		/*
    		连接节点:遍历所有加的点: 
    			if(是最前面的图&&是最前面的点){
    				连后面一个图自己后面的和自己 
    			}else if(是最后面的图){
    				不连 
    			}else{
    				连后面一个图自己前面的和自己
    				连后面一个图自己后面的和自己
    		}*/
    		
    	}
    	for(int i=0;i<=n*30;i++)dis[i]=2000000000;
    	dijkstra();
    	printf("%d
    ",dis[n*k+t]);
    	return 0;
    }
  • 相关阅读:
    让我们一起Go(八)
    让我们一起Go(七)
    让我们一起Go(六)
    VTemplate模板引擎的使用入门篇
    超时时间已过或服务器未响应的解决方法
    SQL Server 2005使用BCP命令将数据表导出到Excel第一行包括表头
    VTemplate模板引擎的使用进阶篇
    VTemplate模板引擎的使用认识篇
    免费开源的模板引擎VTemplate
    .NET 4.5 中新提供的压缩类
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680720.html
Copyright © 2011-2022 走看看