HDU-4725 The Shortest Path in Nya Graph

Topic link

HDU-4725

Title

Given n points and m weighted two-way roads, each of these n points has an attribute called hierarchy. Points between adjacent levels can be transferred by cost c. Find the shortest path of 1-n.

Ideas

This question may be one of the most difficult in the topic of kuangbin. The idea is very clear, the shortest path is naked, and the difficulty lies in drawing. This mapping is different from the one specifically for disgusting people in POJ-2502 . It really requires brainstorming.
Regarding levels, although the level range is 1-n, it does not tell you that all 1-n must appear, nor does it tell you that there is only one point in a level. this means:

  • Offline processing becomes difficult
  • Only two adjacent layers can be connected, such as directly connecting 1-3 layers without processing. If layer 2 does not exist, then this route is not feasible.

The easiest way to think of should be a two-layer for, but the range of n is 1e5, and it will definitely be t. Here we choose to build a layer node for each layer, which is somewhat similar to a super source point and a super sink point. Process each node online, connect the layer node to which this node belongs to a one-way edge (if bidirectional, then the cost of moving all points at the same level to each other is 0, obviously wa), and then connect this node to the upper and lower level nodes One-way side. For the m edges to be connected normally, run the shortest path afterwards
. Attach a sample 2 picture. Node 456 represents the layer node of level 123Example 2

Code

#include<bits/stdc++.h>  
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
using namespace std;
	typedef long long ll;
	typedef pair <int,int> P;
	const int maxn=200500;
	const int maxe=800500;//开大点没坏处 ~ ~ 
	const int inf=0x3f3f3f3f;
	int head[maxn];
	struct Edge{
    
    
		int to;
		int next;
		int w;
	} edge[maxe];
	int cnt;
	int n,m,c;//点,边,跳跃花费 
 	int dis[maxn];
	void init(){
    
    
		cnt=0;
		memset(head,-1,sizeof(head));
		return ;
	}
	inline void add(int u,int v,int w){
    
    
		edge[cnt].next=head[u];
		edge[cnt].to=v;
		edge[cnt].w=w;
		head[u]=cnt;
		cnt++;
	}
			
	void dij(int start){
    
    
		memset(dis,0x3f,sizeof(dis));
		priority_queue<P,vector<P>,greater<P> > q;
		dis[start]=0;
		q.push(P(0,start));
		while(!q.empty()){
    
    
			P p=q.top(); q.pop();
			int v=p.second;
			
			if(dis[v]<p.first)		continue;
			
			for(int i=head[v];i!=-1;i=edge[i].next){
    
    
				int tmp=edge[i].to;
				if(dis[tmp]>dis[v]+edge[i].w){
    
    
					dis[tmp]=dis[v]+edge[i].w;
					q.push(P(dis[tmp],tmp));
				}
			}
		}
		return ;
	}
	int main(){
    
    
		IOS
		int tn;
		cin>>tn;
		for(int _=1;_<=tn;_++){
    
    
			init();
			cin>>n>>m>>c;
			for(int i=1;i<=n;i++){
    
    
				int l;
				cin>>l;
				add(l+n,i,0);//第l层层节点向i节点连单向边 
				if(l<n)
					add(i,l+n+1,c);//i节点向l+1层连单向边 
				if(l>1)
					add(i,l+n-1,c);//i节点向l-1层连单向边 
			}
			while(m--){
    
    
				int u,v,w;
				cin>>u>>v>>w;
				add(u,v,w);
				add(v,u,w);
			}
			dij(1);
			int ans=dis[n];
			if(ans==inf)
				ans=-1; 
			cout<<"Case #"<<_<<": "<<ans<<endl;
		}
		return 0;
	}

Guess you like

Origin blog.csdn.net/TheSunspot/article/details/107746994
Recommended