链式前向星#


在做图论题的时候,偶然碰到了一个数据量很大的题目,用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. R语言统计学习-1简介

    一. 统计学习概述 统计学习是指一组用于理解数据和建模的工具集.这些工具可分为有监督或无监督.1.监督学习:用于根据一个或多个输入预测或估计输出.常用于商业.医学.天体物理学和公共政策等领域.2.无监 ...

  2. CMDB资产管理系统开发【day25】:windows客户端开发

    1.目录结构 PS Y:\MadkingClient> tree /f 卷 netgame 的文件夹 PATH 列表 卷序列号为 ACE3-896E Y:. ├─bin │ NedStark.p ...

  3. MS SQL Server 数据库连接字符串详解

    MS SQL Server 数据库连接字符串详解 原地址:http://blog.csdn.net/jhhja/article/details/6096565 问题 : 超时时间已到.在从池中获取连接 ...

  4. ArcGis Python脚本——根据接图表批量裁切分幅影像

    年前写了一个用渔网工具制作图幅接图表的文章,链接在这里: 使用ArcMap做一个1:5000标准分幅图并编号 本文提供一个使用ArcMap利用接图表图斑裁切一幅影像为多幅的方法. 第一步,将接图表拆分 ...

  5. 点评cat系列-简介

    面上有很多优秀的 OS 级监控系统 (比如 falcon), 这些监控系统主要聚焦在 CPU/IO/Mem/Disk 和应用端口, falcon 甚至可以监控到 JVM. 但对于应用系统内部的一些监控 ...

  6. slot

    本文涉及的slot有:<slot>,v-slot吗,vm.$slots,vm.$scopedSlots 废弃的使用特性:slot,slot-scope,scope(使用v-slot,2.6 ...

  7. python 模块 SQLalchemy

    SQLalchemy 概述: # &&&&&&&&&&&&&&&&&am ...

  8. token的设置与获取

    以用户登录为例: application-resources.yml: #用户session在redis中保存的key REDIS_STU_SESSION_KEY: REDIS_USER_SESSIO ...

  9. 学习总结javascript和ajax,php,和css

    1,javascript 1,js可以获取和修改html的属性和内容: 通过什么获取? window.onload=function{ document.getElementById("xx ...

  10. 2018-2019-1 20189208《Linux内核原理与分析》第九周作业

    活动 main函数编译有问题,div 函数和系统中某个函数重名,浮点输出有问题,scanf也有问题 修改如下 scanf_s("%d %d", &a, &b); p ...