链式前向星#


在做图论题的时候,偶然碰到了一个数据量很大的题目,用vector的邻接表直接超时,上网查了一下发现这道题数据很大,vector可定会超的,不会指针链表的我找到了链式前向星这个好东西,接下来就由一道裸模板题看看链式前向星怎么写,他的优势又在哪里!

题目链接:POJ 2387

Description

Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the morning milking. Bessie needs her beauty sleep, so she wants to get back as quickly as possible.

Farmer John's field has N (2 <= N <= 1000) landmarks in it, uniquely numbered 1..N. Landmark 1 is the barn; the apple tree grove in which Bessie stands all day is landmark N. Cows travel in the field using T (1 <= T <= 2000) bidirectional cow-trails of various lengths between the landmarks. Bessie is not confident of her navigation ability, so she always stays on a trail from its start to its end once she starts it.

Given the trails between the landmarks, determine the minimum distance Bessie must walk to get back to the barn. It is guaranteed that some such route exists.

Input

Line 1: Two integers: T and N

Lines 2..T+1: Each line describes a trail as three space-separated integers. The first two integers are the landmarks between which the trail travels. The third integer is the length of the trail, range 1..100.

Output

Line 1: A single integer, the minimum distance that Bessie must travel to get from landmark N to landmark 1.

Sample Input

5 5

1 2 20

2 3 30

3 4 20

4 5 20

1 5 100

Sample Output

90

题意

很简单的最短路模板题,输一个图进去,不过是先输边数m后输点数n,也算是一个坑吧。

题解:

用链式前向星存图再用Dijistra跑一遍,首先比起邻接表存图,在结构体的构造上就有所不同。

  • 这是链式前向星
struct Edge {
int to;
int w;
int next;
}edge[MAXN];
  • 这是普通的邻接表(vector)
struct Edge {
int to;
int w;
Edge(){}
Edge(int a, int b) {
to = a;
w = b;
}
bool operator<(const Edge a)const {
return w == a.w ? to > a.to:w > a.w;
}
};

其实区别最大的地方就在于链式前向星有了next这个属性,来表明他的下一个边在边数组中的位置,而邻接表是给每个点都分别存他相连的每条边,分开存的,链式前向星全都存在了一起,所有在双向边的时候,要个maxn开2倍大小,邻接表不用考虑这个情况,也算新手的坑吧。

然后是建图操作,用函数封装起来

int head[MAXN];
long long dis[MAXN];
int vis[MAXN];
int cut;
int n, m;
void addedge(int s, int g, int w) {
edge[cut].to = g;
edge[cut].w = w;
edge[cut].next = head[s];
head[s] = cut++;
}

用cut存边的个数,然后进行加边操作,完全不懂加边原理的看这里传送门,这网上的模板用到了两个结构体,一个用来存所有的边,一个用来堆优化的时候构造边,这样也能节省时间和内存吧,让其中一个结构体很轻量,其实链式前向星的原理是有点难搞懂,但是这个代码还是比较简单的。最可怕的是原来79ms的题直接0ms过了,恐怖如斯!!

代码

//#include<bits/stdc++.h>
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#define lson i<<2
#define rson i<<2|1
#define LS l,mid,lson
#define RS mid+1,r,rson
#define mem(a,x) memset(a,x,sizeof(a))
#define gcd(a,b) __gcd(a,b)
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x&-x)
#define pb(x) push_back(x)
#define enld endl
#define mian main
#define itn int
#define prinft printf
#pragma GCC optimize(2)
#pragma comment(linker, "/STACK:102400000,102400000") const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int EXP = 1e-8;
const int N = 1e5 + 5;
const int MOD = 1e9 + 7;
const int MAXN = 4e3 + 5; using namespace std;
struct Edge {
int to;
int w;
int next;
}edge[MAXN];
struct Node {
int to;
int w;
Node(){}
Node(int a, int b) {
to = a;
w = b;
}
bool operator<(const Node a)const {
return w == a.w ? to > a.to:w > a.w;
}
};
int head[MAXN];
long long dis[MAXN];
int vis[MAXN];
int cut;
int n, m;
void addedge(int s, int g, int w) {
edge[cut].to = g;
edge[cut].w = w;
edge[cut].next = head[s];
head[s] = cut++;
}
void Init() {
cut = 0;
mem(vis, false);
mem(dis, INF);
mem(head, -1);
/*for (int i(0); i <= n; i++) {
vis[i] = false;
dis[i] = INF;
head[i] = -1;
}*/
}
Node cur;
void Dijistra(int s) {
priority_queue<Node>P;
P.push(Node(s, 0));
dis[s] = 0;
while (!P.empty()) {
cur = P.top();
P.pop();
int u = cur.to;
if (vis[u])continue;
vis[u] = true;
for (int i = head[u]; ~i; i = edge[i].next) {
int to = edge[i].to;
int w = edge[i].w;
if (!vis[to] && dis[to] > dis[u] + w) {
dis[to] = dis[u] + w;
P.push(Node(to, dis[to]));
}
}
}
}
int main() {
int a, b, c;
while (~scanf("%d%d",&m,&n)) {
Init();
while (m--) {
//cin >> a >> b >> c;
scanf("%d%d%d", &a, &b, &c);
addedge(a, b, c);
addedge(b, a, c);
}
Dijistra(1);
printf("%lld\n", dis[n]);
//cout << dis[n] << endl;
} return 0;
}

链式前向星版DIjistra POJ 2387的更多相关文章

  1. # [Poj 3107] Godfather 链式前向星+树的重心

    [Poj 3107] Godfather 链式前向星+树的重心 题意 http://poj.org/problem?id=3107 给定一棵树,找到所有重心,升序输出,n<=50000. 链式前 ...

  2. POJ 3169 Layout(差分约束+链式前向星+SPFA)

    描述 Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 ...

  3. 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)

    首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...

  4. POJ 1655 Balancing Act ( 树的重心板子题,链式前向星建图)

    题意: 给你一个由n个节点n-1条边构成的一棵树,你需要输出树的重心是那个节点,以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的 题解: 树的重心定义:找到一个点,其所 ...

  5. 【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)

    Dijkstra+ 链式前向星+ 优先队列   Dijkstra算法 Dijkstra最短路算法,个人理解其本质就是一种广度优先搜索.先将所有点的最短距离Dis[ ]都刷新成∞(涂成黑色),然后从起点 ...

  6. 链式前向星+SPFA

    今天听说vector不开o2是数组时间复杂度常数的1.5倍,瞬间吓傻.然后就问好的图表达方式,然后看到了链式前向星.于是就写了一段链式前向星+SPFA的,和普通的vector+SPFA的对拍了下,速度 ...

  7. 单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板

    一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的 ...

  8. hdu2647 逆拓扑,链式前向星。

    pid=2647">原文地址 题目分析 题意 老板发工资,可是要保证发的工资数满足每一个人的期望,比方A期望工资大于B,仅仅需比B多1元钱就可以.老板发的最低工资为888元.输出老板最 ...

  9. 图的存储结构:邻接矩阵(邻接表)&链式前向星

    [概念]疏松图&稠密图: 疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图. Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵. 邻接矩阵: 开一个二维数组gr ...

随机推荐

  1. python httpserver

    python3: python -m http.server 80 python2: python -m SimpleHTTPServer 9004

  2. IaaS,PaaS,SaaS 的区别(转)

    越来越多的软件,开始采用云服务. 云服务只是一个统称,可以分成三大类. IaaS:基础设施服务,Infrastructure-as-a-service PaaS:平台服务,Platform-as-a- ...

  3. SpringBoot入门-2(两种热部署方式)

    在编写代码的时候,你会发现我们只是简单把打印信息改变了,就需要重新部署,如果是这样的编码方式,那么我们估计一天下来就真的是打几个Hello World就下班了.那么如何解决热部署的问题呢?那就是spr ...

  4. 关于java集合的练习

    关于java集合的练习 练习一:Collection集合练习 一.产生10个1-100的随机数,并放到一个数组中,把数组中大于等于10的数字放到一个list集合中,并打印到控制台. public cl ...

  5. 第五节:从源码的角度理解各种Result(ActionResult、JsonResult、JavaScriptResult等)

    一. 背景 提到MVC不得不说MVC中的各种Result,这些高度封装的xxxResult以及在xxxResult再度封装的xxx,大大提高了MVC框架的开发效率. 相信做过MVC开发的朋友都会用到过 ...

  6. MySQL高可用——PXC简介

    序言 Percona XtraDB Cluster(简称PXC集群)提供了MySQL高可用的一种实现方法. PXC属于一套近乎完美的mysql高可用集群解决方案,相比那些比较传统的基于主从复制模式的集 ...

  7. [译]Ocelot - Getting Started

    原文 Ocelot专为.NET Core而设计. .NET Core 2.1 安装 首先需要创建一个netstandard2.0项目,然后再通过nuget安装. Install-Package Oce ...

  8. [译]Ocelot - Headers Transformation

    原文 Add to Request 为上游请求添加请求头,只需如下一样将下面的配置添加到一个ReRoute里: "UpstreamHeaderTransform": { " ...

  9. vue使用md5,base64方法

    在前端加密代码虽然对安全没有提高,但是可以避免明文传输,提供用户隐私保护,还是很有必要的. 首先安装js-md5,js-base64. 在vue中引入. 之后就可以直接使用了,一般的做法是先把密码转行 ...

  10. KL散度

    摘自: https://www.jianshu.com/p/43318a3dc715?from=timeline&isappinstalled=0 一.解决的问题 量化两种概率分布P和Q可以使 ...