链式前向星#


在做图论题的时候,偶然碰到了一个数据量很大的题目,用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. EF CodeFirst系列(5)---FluentApi

    FluentApi总结 1.FluentApi简介 EF中的FluentApi作用是通过配置领域类来覆盖默认的约定.在EF中,我们通过DbModelBuilder类来使用FluentApi,它的功能比 ...

  2. Linux 命令详解(十三)如何启动、关闭和设置ubuntu防火墙

    sudo  ufw enable|disable 由于LInux原始的防火墙工具iptables过于繁琐,所以ubuntu默认提供了一个基于iptable之上的防火墙工具ufw. ubuntu 9.1 ...

  3. 02 Redis关闭服务报错---(error) ERR Errors trying to SHUTDOWN. Check logs.

    127.0.0.1:6379> shutdown (error) ERR Errors trying to SHUTDOWN. Check logs. 1.在redis.conf中修改日志文件的 ...

  4. div宽高不确定,内容居中

    当div的宽高不确定时候,内容居中:// 加在父级div中 垂直居中:align-items:center; display: -webkit-flex;水平居中:justify-content:ce ...

  5. Codeforces Round #447 (Div. 2) B. Ralph And His Magic Field 数学

    题目链接 题意:给你三个数n,m,k;让你构造出一个nm的矩阵,矩阵元素只有两个值(1,-1),且满足每行每列的乘积为k,问你多少个矩阵. 解法:首先,如果n,m奇偶不同,且k=-1时,必然无解: 设 ...

  6. 大数据基础-2-Hadoop-1环境搭建测试

    Hadoop环境搭建测试 1 安装软件 1.1 规划目录 /opt [root@host2 ~]# cd /opt [root@host2 opt]# mkdir java [root@host2 o ...

  7. (一)校园信息通微信小程序从前端到后台整和笔记

    前段时间接触了微信小程序,现在回过头来做一些笔记. 先上效果图 后台数据管理界面(PHP) 校园信息通微信小程序前端界面 下面先简单的说一下怎样部署一个微信小程序 首先是前端 微信小程序有它专门的开发 ...

  8. 一张图让你懂Python安装第三方库

  9. codeforces 1082G - Petya and Graph 最大权闭合子图 网络流

    题意: 让你选一些边,选边的前提是端点都被选了,求所有的边集中,边权和-点权和最大的一个. 题解: 对于每个边建一个点,然后就是裸的最大权闭合子图, 结果比赛的时候我的板子太丑,一直T,(不会当前弧优 ...

  10. SpringBoot入门基础

    目录 SpringBoot入门 (一) HelloWorld. 2 一 什么是springboot 1 二 入门实例... 1 SpringBoot入门 (二) 属性文件读取... 16 一 自定义属 ...