链式前向星和优先队列实现有向图/无向图的最短路)

链式前向星和优先队列实现有向图/无向图的最短路(解题日志)

先看例题poj3268银牛节
题目大意:各个农场派一只奶牛去指定农场参加银牛节,计算在选择最优路径时耗费最多时间。
题目解析:由于m为10^5本题用普通的邻接列表必然超时,因此学习新的方法链式前向星,相比较前向星而言时间复杂度仅为O(m)。
算法解析:该算法是将起点相同的路径归为一类,然后每个路径节点的next指向上一节点,第一个节点则指向-1。
样例实现最终图示(以x为起点)

诶嘿(*・ω< ) 。
添加路径代码

void add(int u,int v,int w){
    
    
	edage1[cnt].to=v;
	edage1[cnt].next=head1[u];
	edage1[cnt].w=w;
	head1[u]=cnt;
}

单起点遍历代码

for(int i=head1[v];i!=-1;i=edage1[i].next){
    
    
	int temp=edage1[i].to;
	if(dis1[temp]>dis1[v]+edage1[i].w){
    
    
		dis1[temp]=dis1[v]+edage1[i].w;
		q.push(P(dis1[temp],temp));				
	}			
}

如果是无向图的话这样就足够了(把路径交换添加),但是此题是有向图,当然有向图也很简单,分开来就行了,需要两张图来存储。
实现代码

void add(int u,int v,int w){
    
    
	edage1[cnt].to=v;
	edage1[cnt].next=head1[u];
	edage1[cnt].w=w;
	head1[u]=cnt;
	
	edage2[cnt].to=u;
	edage2[cnt].next=head2[v];
	edage2[cnt].w=w;
	head2[v]=cnt;
	cnt++;
}

然后就是优先队列的优化,作用就是省去每次查找最短路的时间
最后给出完整代码:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1009;
const int maxe=100000;
typedef int long long ll;
typedef pair <int,int> P;
int head1[maxn],head2[maxn];

struct node{
    
    
	int to;
	int next;
	int w;
}edage1[maxe],edage2[maxe];

int cnt;
int dis1[maxn],dis2[maxn];

void init(){
    
    
	cnt=0;
	memset(dis1,inf,sizeof dis1);
	memset(dis2,inf,sizeof dis2);
	memset(head1,-1,sizeof head1);
	memset(head2,-1,sizeof head2);
}

void add(int u,int v,int w){
    
    
	edage1[cnt].to=v;
	edage1[cnt].next=head1[u];
	edage1[cnt].w=w;
	head1[u]=cnt;
	
	edage2[cnt].to=u;
	edage2[cnt].next=head2[v];
	edage2[cnt].w=w;
	head2[v]=cnt;
	cnt++;
}

void djk1(int start){
    
    
	priority_queue<P,vector<P>,greater<P>>q;
	dis1[start]=0;
	q.push(P(0,start));
	while(!q.empty()){
    
    
		P p=q.top();q.pop();
		int v=p.second;
		
		if(dis1[v]<p.first)continue;
		for(int i=head1[v];i!=-1;i=edage1[i].next){
    
    
			int temp=edage1[i].to;
			if(dis1[temp]>dis1[v]+edage1[i].w){
    
    
				dis1[temp]=dis1[v]+edage1[i].w;
				q.push(P(dis1[temp],temp));				
			}			
		}
	}
	return;
}

void djk2(int start){
    
    
	priority_queue<P,vector<P>,greater<P>>q;
	dis2[start]=0;
	q.push(P(0,start));
	while(!q.empty()){
    
    
		P p=q.top();q.pop();
		int v=p.second;
		if(dis2[v]<p.first)continue;		
		for(int i=head2[v];i!=-1;i=edage2[i].next){
    
    
			int temp=edage2[i].to;
			if(dis2[temp]>dis2[v]+edage2[i].w){
    
    
				dis2[temp]=dis2[v]+edage2[i].w;
				q.push(P(dis2[temp],temp));				
			}			
		}
	}	
	return;
}

int main(){
    
    
	int n,m,x;
	cin>>n>>m>>x;
	init();
	for(int i=0;i<m;++i){
    
    
		int u,v,w;
		cin>>u>>v>>w;
		add(u,v,w);
	}
	djk1(x);djk2(x);
	int ans=0;
	for(int i=1;i<=n;++i){
    
    
		if(dis1[i]!=inf&&dis2[i]!=inf)
		ans=max(ans,dis1[i]+dis2[i]);
	}
	cout<<ans<<endl;	
	return 0;
}

完了。

猜你喜欢

转载自blog.csdn.net/skl4869/article/details/117089601