IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 堆优化Dijkstra()算法+spfa算法(模板) -> 正文阅读

[数据结构与算法]堆优化Dijkstra()算法+spfa算法(模板)

题目链接

题意:

T组样例
n个顶点,m条单向边
m行 ui,vi,wi.
求源点1到其它点来回最短路
最后输出所有来回最短路相加之和
0<n≤20000,m≤60000,1≤T≤10,0≤ci?≤10^9,1≤ui?,vi,wi?≤n

题解:
单源最短路,且边权值为正数,n数据太大,邻接表存图。
解法1:spfa算法

解法2:堆优化Dijkstra()算法
如何实现堆优化:

  1. 不同结构体,用pair容器,pair可以放两个元素,相当于一个结构体,然后优先队列自动从小到大排序,排序先按pair中第一个元素排,然后才考虑第二个元素。
  2. 用结构体,结构体中放一个排序,其实我认为这个比较简单。

:其实相比迪杰斯特拉算法只是多了一个堆排序,为了更快的找到最小值而已;还有不需要数组标记,根据贪心思想找最小值,不用找就在队列的第一个,而下面的松弛不需要判断是否被标记过,如果v已经被标记,if()肯定不满足的。

代码1:spfa()

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+10;
const ll INF=0x3f3f3f3f3f3f3f3f;
ll first[N],nx[N],to[N],s[N],head=1;
ll u[N],v[N],w[N];
ll dis[N],dis1[N],dis2[N],book[N];
void init()
{
	head=1;
	memset(first,-1,sizeof(first));
}
void add(ll x,ll y,ll z)
{
	nx[head]=first[x];
	first[x]=head;
	to[head]=y;
	s[head]=z;
	head++;
}
void spfa(ll x)
{
	ll i,u,v;
	memset(book,0,sizeof(book));
	memset(dis,INF,sizeof(dis));
	dis[x]=0;
	book[x]=1;
	queue<ll> q;
	q.push(x);
	while(!q.empty())
	{
		u=q.front();
		q.pop();
		book[u]=0;
		for(i=first[u];i!=-1;i=nx[i])
		{
			v=to[i];
			if(dis[v]>dis[u]+s[i])
			{
				dis[v]=dis[u]+s[i];
				if(!book[v])
				{
					book[v]=1;
					q.push(v); 
				}
			}
		}
	}
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		init();
		ll n,m,i;
		scanf("%lld %lld",&n,&m);
		for(i=1;i<=m;i++)
		{
			scanf("%lld %lld %lld",&u[i],&v[i],&w[i]);
			add(u[i],v[i],w[i]);
		}
		spfa(1);
		for(i=1;i<=n;i++)	dis1[i]=dis[i];
		init();
		for(i=1;i<=m;i++)
			add(v[i],u[i],w[i]);
		spfa(1);
		for(i=1;i<=n;i++)	dis2[i]=dis[i];
		ll ans=0;
		for(i=2;i<=n;i++)
			ans+=dis1[i]+dis2[i];
		printf("%lld\n",ans);
	}
	return 0;
}

代码2:pair

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pr;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll N=20020;
const ll M=60060;
ll first[N],nx[M],to[M],s[M],head;
ll dis[N],dis1[N],dis2[N];
ll u[M],v[M],w[M];
ll n,m;
void init()
{
	head=1;
	memset(first,-1,sizeof(first));
}
void add(ll x,ll y,ll z)
{
	nx[head]=first[x];
	to[head]=y;
	s[head]=z;
	first[x]=head++;
}
void dui_Dijkstra(ll x)
{
	priority_queue<pr,vector<pr>,greater<pr> >Q;
	memset(dis,INF,sizeof(dis));
	dis[x]=0;
	Q.push({dis[x],x});
	ll u,v,i;
	while(!Q.empty())
	{
		u=Q.top().second;
		Q.pop();
		for(i=first[u];i!=-1;i=nx[i])
		{
			v=to[i];
			if(dis[v]>dis[u]+s[i])
			{
				dis[v]=dis[u]+s[i];
				Q.push({dis[v],v});
			}
		}
	}
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		init();
		scanf("%lld %lld",&n,&m);
		for(int i=1;i<=m;i++)
		{
			scanf("%lld %lld %lld",&u[i],&v[i],&w[i]);
			add(u[i],v[i],w[i]);
		}
		dui_Dijkstra((ll)1);
		for(int i=1;i<=n;i++)	dis1[i]=dis[i];
		init();
		for(int i=1;i<=m;i++)
			add(v[i],u[i],w[i]);
		dui_Dijkstra((ll)1);
		for(int i=1;i<=n;i++)	dis2[i]=dis[i];
		ll ans=0;
		for(int i=2;i<=n;i++)
			ans+=dis1[i]+dis2[i];
		printf("%lld\n",ans);
	} 
	return 0;
}

代码3:结构体

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll N=20020;
const ll M=60060;
ll first[N],nx[M],to[M],s[M],head;
ll dis[N],dis1[N],dis2[N],book[N];
ll u[M],v[M],w[M];
ll n,m;
void init()
{
	head=1;
	memset(first,-1,sizeof(first));
}
struct Node{
	ll p,s;
	bool operator <(const Node &W)const
	{
		return s<W.s;
	}
};
void add(ll x,ll y,ll z)
{
	nx[head]=first[x];
	to[head]=y;
	s[head]=z;
	first[x]=head++;
}
void dui_Dijkstra(ll x)
{
	queue<Node> Q;
	struct Node _u,_v;
	memset(dis,INF,sizeof(dis));
	dis[x]=0;
	_v={x,dis[x]};
	Q.push(_v);
	book[x]=1;
	ll u,v,i;
	while(!Q.empty())
	{
		_u=Q.front();
		u=_u.p;
		Q.pop();
		for(i=first[u];i!=-1;i=nx[i])
		{
			v=to[i];
			if(dis[v]>dis[u]+s[i])
			{
				dis[v]=dis[u]+s[i];
				_v={v,dis[v]};
				Q.push(_v);
			}
		}
	}
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		init();
		scanf("%lld %lld",&n,&m);
		for(int i=1;i<=m;i++)
		{
			scanf("%lld %lld %lld",&u[i],&v[i],&w[i]);
			add(u[i],v[i],w[i]);
		}
		dui_Dijkstra((ll)1);
		for(int i=1;i<=n;i++)	dis1[i]=dis[i];
		init();
		for(int i=1;i<=m;i++)
			add(v[i],u[i],w[i]);
		dui_Dijkstra((ll)1);
		for(int i=1;i<=n;i++)	dis2[i]=dis[i];
		ll ans=0;
		for(int i=2;i<=n;i++)
			ans+=dis1[i]+dis2[i];
		printf("%lld\n",ans);
	} 
	return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:36:03  更:2022-04-04 12:38:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:31:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码