堆优化dijkstra

#include<vector>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int maxn=1e5,maxn_1=1e5*2;
typedef pair<int,int> PII;
/*
//方法1
struct tmp1 //运算符重载<
{
    int x;
    tmp1(int a) {x = a;}
    bool operator<(const tmp1& a) const
    {
        return x < a.x; //大顶堆
    }
};

//方法2
struct tmp2 //重写仿函数
{
    bool operator() (tmp1 a, tmp1 b) 
    {
        return a.x < b.x; //大顶堆
    }
};
*/
struct node{
	int step;
	PII pa;
};
bool operator<(const node &a,const node &b){ //小根堆
	return a.step>b.step;
}
/**********链式前向星存图************/
struct{
	int to,next,val;
}eg[maxn_1];
int head[maxn],cnt=0;
//memset(head,-1,sizeof(head));
void add(int x,int y,int z){
	eg[cnt].to=y;
	eg[cnt].val=z;
	eg[cnt].next=head[x];
	head[x]=cnt++;
}
/**********************************/


/*************vecctor存图*************/
vector<pair<int,int> >::iterator it;
vector<pair<int,int> > g[maxn];
void add(int x,pair<int,int> y){
	g[x].insert(g[x].begin(),y);
}
/***********************************/
int vis[maxn];
bool bis[maxn];

priority_queue<PII,vector<PII>,greater<PII> >q; 
priority_queue<PII,vector<PII>,less<PII> >q; 
int dij(int x){  //链式前向星
	memset(vis,0x3f,sizeof(vis));
	memset(bis,0,sizeof(bis));
	q.push({0,x});   //起点x,初始距离为0
	while(!q.empty()){
		PII pi=q.top();q.pop();
		int first=pi.first,second=pi.second;
		if(bis[second])continue;
		bis[second]=1;
		for(int i=head[second];i!=-1;i=eg[i].next){
			int j=eg[i].to;
			if(!bis[j]&&vis[j]>first+eg[i].val){
				vis[j]=first+eg[i].val;
				q.push({vis[j],j});
			}
		}
	} 
	//for(int i=0;i<=10;i++)cout<<vis[i]<<" ";cout<<endl;
}
void dij_v(int x){   //vector
	memset(vis,0x3f,sizeof(vis));
	memset(bis,0,sizeof(bis));
	q.push({0,x});   //起点x,初始距离为0
	while(!q.empty()){
		PII pi=q.top();q.pop();
		int first=pi.first,second=pi.second;
		if(bis[second])continue;
		bis[second]=1;
		for(it=g[second].begin();it!=g[second].end();it++){
			int j=it->first;
			if(!bis[j]&&vis[j]>first+it->second){
				vis[j]=first+it->second;
				q.push({vis[j],j});
			}
		}
	} 
	//for(int i=0;i<=10;i++)cout<<vis[i]<<" ";cout<<endl;
}
int main(){
	memset(head,-1,sizeof(head));
	int n,m;cin>>n>>m;
	for(int i=0;i<m;i++){
		int x,y,z;cin>>x>>y>>z;
		add(x,y,z);add(y,x,z);
		add(x,{y,z});add(y,{x,z});
	}
	dij(1);dij_v(1);
	return 0;
}
全部评论

相关推荐

10-02 19:29
已编辑
浙江科技大学 运营
点赞 评论 收藏
分享
一天代码十万三:这个学历有中大厂实习也是0面,没办法,斩杀线是这样的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务