这里借这个题讲一下什么是链式前向星和他的用处:

一.链式前向星

1.由来:我们都知道图的存储方式有链接矩阵,邻接表两种,邻接矩阵好写但是占内存大,数稍微大点的题目就开不下数组了(适合稠密图);邻接表的指针形式难写易错,vector形式读取太慢大数据下会TLE。那怎么办?这里就产生了一种比较中庸的方式:

链式前向星。

2.概念:听名字,链式前向星就是把数据以链表形式连在一起,那么链接的条件是什么呢?我们回想一下图里面邻接表里存的是每个点的连接点。那么这里的链式前向星存的就是以每个点为起点的所有边。

3.需要:

(1)head[maxn]数组,head[id]表示以 id 点为起点的第一条边,也就是查询以这个点为起点的所有边的开始点,也就是链表头部

(2)

struct Node//Node结构体,存储每条边的终点to , 连在同一起点上的下一条边的编号next , 权值v
{int to,next,v;
};

(3)

void AddEdge(int a,int b,int c)//加边函数,连一条以a为起点到达b权值为c的边
{node[tot].next = head[a];node[tot].to = b;node[tot].flag = c;head[a] = tot++;
}//这里开始链表骚操作:这段代码是核心,也很好理解就是不断把边的编号连在链表上(tot表示边的编号)

注:(head一般初始化为-1)

很明显,head[i]保存的是以i为起点的所有边中编号最大的那个,而把这个当作顶点i的第一条起始边的位置.

这样在遍历时是倒着遍历的,也就是说与输入顺序是相反的,不过这样不影响结果的正确性.

比如以上图为例,以节点1为起点的边有3条,它们的编号分别是0,3,5   而head[1] = 5

我们在遍历以u节点为起始位置的所有边的时候是这样的:

for(int i=head[u];~i;i=edge[i].next)

那么就是说先遍历编号为5的边,也就是head[1],然后就是edge[5].next,也就是编号3的边,然后继续edge[3].next,也

就是编号0的边,可以看出是逆序的.

下面看一下链式前向星的强大:

二.HDU - 6386  Age of Moyu

题意:给你n个港口,m个路线。接下来m行给你a,b,c代表从a港口到b港口是航线c。题目规定在一条航线上行驶花费始终为1,但是如果改变一次航线,则花费就增加1。问你从初始1港口到达n港口所需要的最小花费

分析:

(1)思路方面:在做的时候第一想法是用并查集维护一条航线上的点,把同一条航线之间全部两两连线,长度都归为1。然后再跑一遍最短路。但是在两两连线的时候就涉及到了怎么连能减少时间开销,然后gg;

后来发现其实不用并查集,用一个结构体记录一下到该港口的目前花费,然后从该港口p出发去其他港口q时,要判断pq之间航线和到达p的航线是否相同相同的话cost + 0.否则cost + 1;然后更新dis存入队列。(越想越觉得像个优先队列做的BFS)所以还要记录的是到达港口p的航线是什么。这样搜下去就能找到最优答案了。

(2)实现方面:直接vector邻接表超时gg,是vector的查找太慢了,需要用链式前向星。

(3)代码:

#include <iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 200000 + 10;
typedef pair<int,int> P;
struct Node//结构体进行链式前向星存图
{int to,next,flag;//终点 + 下个边编号 + 当前航线
};
Node node[2*maxn];
int dis[maxn],head[maxn];
bool judge[maxn];
int n,m,tot;
void AddEdge(int a,int b,int c)//加边函数(分配编号)
{node[tot].next = head[a];node[tot].to = b;node[tot].flag = c;head[a] = tot++;
}
struct Arrive//在跑最短路时记录前导航线 + 目前花费 + 当前港口
{int flagin,val,portid;bool operator <(const Arrive &another)const{//按照花费由小到大排序return val>another.val;}Arrive(int a,int b,int c):flagin(a),val(b),portid(c) {}
};
void Dijkstra(int a)
{priority_queue<Arrive>que;que.push(Arrive(0,0,a));while(!que.empty()){Arrive p = que.top();que.pop();int id = p.portid;if(judge[id])continue;judge[id] = 1;for(int i = head[id];~i;i = node[i].next){//遍历链式前向星int cost = p.val + (p.flagin==node[i].flag?0:1);//估测花费(判断航线是否一致)if(dis[node[i].to]>cost&&!judge[node[i].to]){//更新dis[node[i].to] = cost;que.push(Arrive(node[i].flag,cost,node[i].to));}}}
}
int main()
{while(scanf("%d%d",&n,&m)!=EOF){tot = 0;//初始化memset(dis,INF,sizeof(dis));//这个地方用mem A了而且时间很短,用循环超时QAQ//for(int i = 0;i<=n;i++)dis[i] = INF;memset(judge,0,sizeof(judge));memset(head,-1,sizeof(head));for(int i = 0;i<m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);AddEdge(a,b,c);//无向图双向建边AddEdge(b,a,c);}dis[1] = 0;Dijkstra(1);printf("%d\n",dis[n]==INF?-1:dis[n]);}return 0;
}

多校第七场A---Age of Moyu 链式前向星+Dijkstra相关推荐

  1. Day 7 A - Age of Moyu HDU 6386 | 最短路 | SPFA | 链式前向星

    松弛:原来用一根橡皮筋连接p和w两点,现在有一点v到w的路径更短,现在把橡皮筋w点的另一端p换成v点,这样缓解橡皮筋紧绷的压力,让其变得松弛. 来自:原博 关于SPFA算法 来自:原博 链式前向星 # ...

  2. 杭电多校第七场 1011 Kejin Player HDU(6656)

    杭电多校第七场 1011 Kejin Player 题意:给你N行,代表从i级有花费a[i]元的r[i]/s[i]的概率达到i+1级,剩下的概率中可能会到达x[i]级.然后询问从L级到R级的花费会是多 ...

  3. 2019杭电多校 第七场 Kejin Player 6656(求期望值)

    2019杭电多校 第七场 Kejin Player 6656(求期望值) 题目 http://acm.hdu.edu.cn/showproblem.php?pid=6656 题意 给你n,q.表示有n ...

  4. HDU6386 Age of Moyu (2018多校第七场1001) (建虚点+堆优化dijkstra)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=6386 题意: n个点m条边,每个边上有一个编号: 从一个编号走到另一个编号,需要代价1: 求1到n的最小代 ...

  5. HDU 2020 多校第七场 游记

    又是被 djq 带飞的一场 orz,终场 rk2,又是罚时被锤了 1001,1002 俩 hard 先略过,不会做 /ll 1003 这种数数神题被 djq 一眼秒了,我还能说什么-- 首先我们考虑合 ...

  6. 2019牛客多校第七场E Find the median 权值线段树+离散化

    Find the median 题目链接: https://ac.nowcoder.com/acm/contest/887/E 题目描述 Let median of some array be the ...

  7. 2019牛客多校 第七场 B Irreducible Polynomial 多项式因式分解判断

    链接:https://ac.nowcoder.com/acm/contest/887/B 来源:牛客网 Irreducible Polynomial 时间限制:C/C++ 1秒,其他语言2秒 空间限制 ...

  8. 2019HDU多校第七场 HDU6656 Kejin Player H 【期望递归】

    一.题目 Kejin Player H 二.分析 因为在当前等级$i$,如果升级失败可能会退回到原来的某一等级$x$,相当于就是失败的期望就是$E + (Sum[i-1] - Sum[x-1]) + ...

  9. 2019杭电多校第七场 HDU - 6656 Kejin Player 期望

    题目链接:https://vjudge.net/problem/HDU-6656 题解: 维护一个前缀sum[i] : 从1到 i 的期望 第 i 到达 i + 1是:ai + (1 - r[i] / ...

最新文章

  1. 深入学习JavaScript: apply call方法 详解(转)
  2. 用VS Code直接浏览GitHub代码 | 12.1K星
  3. Python 字符串的内置函数
  4. Windows.etc\hosts文件
  5. 30,000人如何帮助挑选新的Bash徽标
  6. [Python学习]错误篇二:切换当前工作目录时出错——FileNotFoundError: [WinError 3] 系统找不到指定的路径...
  7. 材料成型及控制工程学计算机吗,材料成型及控制工程 硕士以后 工资多少,
  8. rufus中gpt和mrb磁盘_SSD固态硬盘用GPT还是MBR分区?
  9. 【字节前端青训营】跟着月影学JavaScript——前端代码优化三大原则之各司其职,夜间模式小案例
  10. mysql等保测评命令_Mysql等保部分加固
  11. 搭建NAT64/DNS6实现IPv4/v6转换
  12. Excel读写合集:Excel读写小白从不知所措到轻松上手
  13. Class::DBI模块简介
  14. 罗永浩疑回应再被强制执行
  15. 编写函数求阶乘(完整版)
  16. rust 调用 java_自从尝了 Rust,Java 突然不香了
  17. 内核自带的基于GPIO的LED驱动学习(三)
  18. 百度编辑器(ueditor)踩坑,图片转存无法使用
  19. 手机浏览器加载不出来css,如何解决浏览器不加载css文件的问题
  20. 【通俗易懂】从贝叶斯公式到卡尔曼滤波

热门文章

  1. java的nextint种子_java.util.Scanner.nextInt(int radix)方法实例
  2. 二级计算机c语言模拟考试程序,计算机二级c语言模拟考试题
  3. element-ui 使用时遇到的一些坑
  4. Android 用一个监听器实现多个监听
  5. 营收增长乏力亏损连连 人造肉第一股Beyond Meat何时出坑?
  6. 2020.11.2文献4阅读《Historical Earthquake Damage to Tunnels in Japan and Case Studies...》
  7. linux提示Enter passphrase for key
  8. tableau:漏斗图
  9. 10从零开始学Java之开发Java必备软件Intellij idea的安装配置与使用
  10. junchuang.ren全心只为退役军人再就业