当前位置: 首页 > news >正文

网站设计的价格深圳网站建设运营

网站设计的价格,深圳网站建设运营,昆山张浦做网站,毕业设计动漫网页设计文章目录 算法模板Dijkstra题目代码模板朴素dijkstra算法堆优化版dijkstra 树与图的存储(1) 邻接矩阵:(2) 邻接表:关于e[],ne[],h[]的理解 关于堆的原理与操作 模板题Dijkstra求最短路 I原题链接题目思路题解 Dijkstra求最短路 II原题链接题目思路题解 1…

文章目录

  • 算法模板
    • Dijkstra题目代码模板
      • 朴素dijkstra算法
      • 堆优化版dijkstra
    • 树与图的存储
      • (1) 邻接矩阵:
      • (2) 邻接表:
      • 关于e[],ne[],h[]的理解
    • 关于堆的原理与操作
  • 模板题
    • Dijkstra求最短路 I
      • 原题链接
      • 题目
      • 思路
      • 题解
    • Dijkstra求最短路 II
      • 原题链接
      • 题目
      • 思路
      • 题解
    • 1003 Emergency
      • 原题链接
      • 题目
      • 思路
      • 题解

算法模板

在这里插入图片描述

Dijkstra题目代码模板

朴素dijkstra算法

对应模板题:Dijkstra求最短路 I
时间复杂是 O(n^2+m):n 表示点数,m 表示边数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

int g[N][N];  // 存储每条边
int dist[N];  // 存储1号点到每个点的最短距离
bool st[N];   // 存储每个点的最短路是否已经确定// 求1号点到n号点的最短路,如果不存在则返回-1
int dijkstra()
{memset(dist, 0x3f, sizeof dist);dist[1] = 0;for (int i = 0; i < n - 1; i ++ ){int t = -1;     // 在还未确定最短路的点中,寻找距离最小的点for (int j = 1; j <= n; j ++ )if (!st[j] && (t == -1 || dist[t] > dist[j]))t = j;// 用t更新其他点的距离for (int j = 1; j <= n; j ++ )dist[j] = min(dist[j], dist[t] + g[t][j]);st[t] = true;}if (dist[n] == 0x3f3f3f3f) return -1;return dist[n];
}

堆优化版dijkstra

对应模板题:Dijkstra求最短路 II
时间复杂度 O(mlogn):n 表示点数,m 表示边数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

typedef pair<int, int> PII;int n;      // 点的数量
int h[N], w[N], e[N], ne[N], idx;       // 邻接表存储所有边
int dist[N];        // 存储所有点到1号点的距离
bool st[N];     // 存储每个点的最短距离是否已确定// 求1号点到n号点的最短距离,如果不存在,则返回-1
int dijkstra()
{memset(dist, 0x3f, sizeof dist);dist[1] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1});      // first存储距离,second存储节点编号while (heap.size()){auto t = heap.top();heap.pop();int ver = t.second, distance = t.first;if (st[ver]) continue;st[ver] = true;for (int i = h[ver]; i != -1; i = ne[i]){int j = e[i];if (dist[j] > distance + w[i]){dist[j] = distance + w[i];heap.push({dist[j], j});}}}if (dist[n] == 0x3f3f3f3f) return -1;return dist[n];
}

树与图的存储

树是一种特殊的图,与图的存储方式相同。
对于无向图中的边ab,存储两条有向边a->b, b->a。
因此我们可以只考虑有向图的存储。

(1) 邻接矩阵:

g[a][b] 存储边a->b

(2) 邻接表:

https://www.acwing.com/video/21/
(1:20:00左右)

// 对于每个点k,开一个单链表,存储k所有可以走到的点。h[k]存储这个单链表的头结点
int h[N], e[N], ne[N], idx;// 添加一条边a->b
void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}int main(){...// 初始化idx = 0;memset(h, -1, sizeof h);...
}

有权重时模板:

int h[N],w[N],e[N],ne[N],idx; void add(int a,int b,int c){e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}

关于e[],ne[],h[]的理解

在这里插入图片描述
h[N] : 表示 第 i 个节点的 第一条边的 idx
ne[M] : 表示 与 第 idx 条边 同起点 的 下一条边 的 idx
e[M] : 表示 第idx 条边的 终点

N : 节点数量
M:边的数量
i : 节点的下标索引
idx : 边的下标索引
变量初始化定义:

int h[N], e[M], ne[M], idx;

当我们加入一条边的时候:

void add(int a,int b){e[idx] = b;      // 记录 加入的边 的终点节点ne[idx] = h[a]; // h[a] 表示 节点 a 为起点的第一条边的下标,ne[idx] = h[a] 表示把 h[a] 这条边接在了 idx 这条边的后面,其实也就是把 a 节点的整条链表 接在了 idx 这条边 后面;目的就是为了下一步 把 idx 这条边 当成 a 节点的单链表的 第一条边,完成把最新的一条边插入到 链表头的操作;h[a] = idx++; // a节点开头的第一条边置为当前边,idx移动到下一条边
}

要注意的是邻接表插入新节点时使用的是“头插”,如图中节点2:当插入2 1时此时为2—>1, 而后插入2 4后,此时为 2—> 4 —> 1.
在这里插入图片描述

关于堆的原理与操作

二、数据结构10:堆 模板题+算法模板(堆排序,模拟堆)

模板题

Dijkstra求最短路 I

原题链接

https://www.acwing.com/problem/content/851/

题目

给定一个 n
个点 m
条边的有向图,图中可能存在重边和自环,所有边权均为正值。

请你求出 1
号点到 n
号点的最短距离,如果无法从 1
号点走到 n
号点,则输出 −1

输入格式
第一行包含整数 n
和 m

接下来 m
行每行包含三个整数 x,y,z
,表示存在一条从点 x
到点 y
的有向边,边长为 z

输出格式
输出一个整数,表示 1
号点到 n
号点的最短距离。

如果路径不存在,则输出 −1

数据范围
1≤n≤500
,
1≤m≤105
,
图中涉及边长均不超过10000。

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3

思路

在这里插入图片描述
在这里插入图片描述

题解

#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
const int M = 1e5 + 10;
int dist[N]; // 存各点与1号点的最短距离 
bool st[N]; // 存各点是否已被 处理为最短距离点 判断 (当前已确定最短距离的点) 
int g[N][N];
int n,m,t;int dijkstra(){memset(dist,0x3f,sizeof dist);dist[1] = 0;for(int i = 0;i<n;i++){t = -1; //	t: 不在 当前已确定最短距离的点 中的距离最短的点 初始化为-1 for(int j = 1;j<=n;j++){if(!st[j] && (t == -1 || dist[t] > dist[j])){t = j;}}st[t] = true;for(int j=1;j<=n;j++){dist[j] = min(dist[j],dist[t] + g[t][j]); //用(1到t+t到j)的长度与(1到j)的长度进行对比更新 }}if(dist[n] == 0x3f3f3f3f) return -1;else return dist[n];
}
int main(){cin>>n>>m;memset(g,0x3f,sizeof g);for(int i=0;i<m;i++){int x,y,z;cin>>x>>y>>z;g[x][y] = min(g[x][y],z);}	int res = dijkstra();printf("%d",res);return 0;}

Dijkstra求最短路 II

原题链接

https://www.acwing.com/problem/content/852/

题目

给定一个 n
个点 m
条边的有向图,图中可能存在重边和自环,所有边权均为非负值。

请你求出 1
号点到 n
号点的最短距离,如果无法从 1
号点走到 n
号点,则输出 −1

输入格式
第一行包含整数 n
和 m

接下来 m
行每行包含三个整数 x,y,z
,表示存在一条从点 x
到点 y
的有向边,边长为 z

输出格式
输出一个整数,表示 1
号点到 n
号点的最短距离。

如果路径不存在,则输出 −1

数据范围
1≤n,m≤1.5×105
,
图中涉及边长均不小于 0
,且不超过 10000

数据保证:如果最短路存在,则最短路的长度不超过 109

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3

思路

使用堆优化,选择用stl中的priority_queue进行操作
在这里插入图片描述
关于st[N]数组 处理冗余部分
https://www.acwing.com/solution/content/167860/

题解

#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
const int M = 2e5 + 10;
typedef pair<int,int> PII;
int dist[N]; // 存各点与1号点的最短距离 
bool st[N]; // 存各点是否已被 处理为最短距离点 判断 (当前已确定最短距离的点) 
//int g[N][N];
//堆优化中,由于为稀疏图,因此使用邻接表进行存储
int h[N],w[N],e[N],ne[N],idx; int n,m,t;//邻接表插入处理 
void add(int a,int b,int c){e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}int dijkstra(){memset(dist,0x3f,sizeof dist);dist[1] = 0;//	堆优化版dijkstrapriority_queue<PII,vector<PII>,greater<PII>> heap;heap.push({0,1}); // {距离,编号}编号为1的点距离为0,表示1到1的距离为0 while(heap.size()){auto t = heap.top();heap.pop();int ver = t.second, distance = t.first; // distance :结点1到结点ver的距离if(st[ver]) continue;  // 冗余的话跳过st[ver] = true;for(int i=h[ver]; i!=-1; i=ne[i]){ // 邻接表遍历,从h[ver]开始遍历可达的所有结点int j = e[i];//			w[i]:结点ver到结点j的距离if(dist[j]>distance + w[i]){ // 1--->i的距离 和 1--->ver--->i的距离相比dist[j] = distance + w[i]; heap.push({dist[j],j});}} }if(dist[n] == 0x3f3f3f3f) return -1;else return dist[n];
}
int main(){cin>>n>>m;
//	memset(g,0x3f,sizeof g);memset(h,-1,sizeof h);;for(int i=0;i<m;i++){int x,y,z;cin>>x>>y>>z;add(x,y,z);}	int res = dijkstra();printf("%d",res);return 0;}

1003 Emergency

原题链接

原题链接

题目

题目大意:n个城市m条路,每个城市有救援小组,所有的边的边权已知。给定起点和终点,求从起点到终点的最短路径条数以及最短路径上的救援小组数目之和。如果有多条就输出点权(城市救援小组数目)最大的那个

思路

用一遍Dijkstra算法,救援小组个数相当于点权,用Dijkstra求边权最小的最短路径的条数,以及这些最短路径中点权最大的值
dis[i]表示从出发点到i结点最短路径的路径长度,
num[i]表示从出发点到i结点最短路径的条数,
w[i]表示从出发点到i点救援队的数目之和
当判定dis[u] + e[u][v] < dis[v]的时候,
不仅仅要更新dis[v],还要更新num[v] = num[u], w[v] = weight[v] + w[u];
如果dis[u] + e[u][v] == dis[v],还要更新num[v] += num[u],而且判断一下是否权重w[v]更小,如果更小了就更新w[v] = weight[v] + w[u];

题解

基于上述朴素版dijkstra进行改进,

#include <bits/stdc++.h>
using namespace std;
//题目大意:n个城市m条路,每个城市有救援小组,所有的边的边权已知。给定起点和终点,求从起点到终点的最短路径条数以及最短路径上的救援小组数目之和。如果有多条就输出点权(城市救援小组数目)最大的那个~
//
//分析:用一遍Dijkstra算法~救援小组个数相当于点权,用Dijkstra求边权最小的最短路径的条数,以及这些最短路径中点权最大的值~dis[i]表示从出发点到i结点最短路径的路径长度,num[i]表示从出发点到i结点最短路径的条数,w[i]表示从出发点到i点救援队的数目之和~当判定dis[u] + e[u][v] < dis[v]的时候,不仅仅要更新dis[v],还要更新num[v] = num[u], w[v] = weight[v] + w[u]; 如果dis[u] + e[u][v] == dis[v],还要更新num[v] += num[u],而且判断一下是否权重w[v]更小,如果更小了就更新w[v] = weight[v] + w[u]; const int N = 510;
int g[N][N];
int c1,c2;
int dist[N]; //dist[i]表示从出发点到i结点最短路径的路径长度
int weight[N]; //每个城市救援队数量
int w[N]; //w[i]表示从出发点到i点救援队的数目之和
bool st[N]; 
int num[N]; //num[i]表示从出发点到i结点最短路径的条数int n,m;void dij(){w[c1] = weight[c1];memset(dist,0x3f,sizeof dist);dist[c1] = 0;num[c1] = 1;int t;for(int i=0;i<n;i++){t = -1;for(int j=0;j<n;j++){if(!st[j] && (t==-1 || dist[t] >dist[j]) ){t = j;}}st[t] = true;for(int j=0;j<n;j++){
//			dist[j] = min(dist[j],dist[t] + g[t][j]);if(dist[j]>dist[t]+g[t][j]){ //当判定dis[u] + e[u][v] < dis[v]的时候,不仅仅要更新dis[v],还要更新num[v] = num[u], w[v] = weight[v] + w[u]; dist[j] = dist[t]+g[t][j];num[j] = num[t];w[j] = w[t] + weight[j];  
//				cout<<t<<" "<<w[t]<<endl;
//				w[j]+=weight[t];}else if(dist[j]==dist[t]+g[t][j]){ //如果dis[u] + e[u][v] == dis[v],还要更新num[v] += num[u],而且判断一下是否权重w[v]更小,如果更小了就更新w[v] = weight[v] + w[u]; num[j] = num[t]+num[j];if(w[t]+weight[j] > w[j]){w[j] = w[t] + weight[j];}}	}}//	return w[c2];	
}
int main(){cin>>n>>m>>c1>>c2;for(int i=0;i<n;i++){int t;cin>>t;weight[i] = t;}memset(g,0x3f,sizeof g); // 赋值无穷大 for(int i=0;i<m;i++){int x,y,z;cin>>x>>y>>z;g[x][y] = g[y][x] = z; // 无向图!所以存双向信息 }dij();cout<<num[c2]<<" "<<w[c2];
} 

参考链接:1003. Emergency (25)-PAT甲级真题(Dijkstra算法)

http://www.tj-hxxt.cn/news/39327.html

相关文章:

  • 全国建造师查询网站qq群排名优化软件
  • 北京中联建设集团官网网站百度关键词
  • 上海做网站公司qinmoo企业网络营销目标
  • 楚雄网站开发seo是什么意思中文翻译
  • 模板网站建设 报价许昌网站推广公司
  • 深圳开发网站建设哪家好品牌推广的意义
  • 网站优化seo网站架构优化南宁seo外包服务
  • 做网站遵义百度推广登录入口
  • 在线视频网站 一级做爰片网站建设制作教程
  • 网页制作与网站建设技术大全 pdf网页生成app
  • 免费全能网站空间关键词排名优化工具有用吗
  • ubuntu做网站武汉网络推广有限公司
  • 哪个网站 可以做快递单录入优化营商环境的金句
  • 如何下载js做的网站河南今日头条新闻
  • 做一个京东网站怎么做的百度推广平台登录
  • 做店铺装修的公司网站广告软文外链平台
  • 设计电子商务网站建设方案seo点击排名
  • wordpress 插件 安装教程视频点击宝seo
  • 网站建设公司找上海站霸seo优化是啥
  • 苏州园区做网站重庆网站seo诊断
  • 企业推广网站seo合作代理
  • 手机优化助手怎么删除青岛seo建站
  • 湖南做网站 都来磐石网络网络营销工具分析
  • 创业 建网站网站的宣传推广方式
  • wordpress job 插件seo高效优化
  • 零基础学做网站页关键词优化seo排名
  • 做网站和app怎么跑业务株洲seo
  • wordpress拼图seo技术最新黑帽
  • 家教网站域名怎么做百度一下主页官网
  • 葡京网站做中间商百度电脑版下载