BZOJ 4152 浅谈堆优化的SPFA算法
来源:互联网 发布:java程序员兼职 编辑:程序博客网 时间:2024/06/15 11:04
世界真的很大
其实这道题一看就能想到最短路
关键是怎么建边
看一下数据,200000个点
每个点两两建边的话肯定会超时
好像说多了先看一下题吧:
description
给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。
input
第一行包含一个正整数n(2<=n<=200000),表示点数。接下来n行,每行包含两个整数x[i],y[i](0<=x[i],y[i]<=10^9),依次表示每个点的坐标。
output
一个整数,即最小费用。
首先是最短路没错了
关键是考虑一下怎么建边
认真看一下题
对每一个点来说,想要到它无非两种方法,通过x或y。换个角度想,从一个点到任意另一个点,直接通过距离的费用肯定大于等于通过x或y相邻的点搭桥过去
因为直接过去是直接x坐标或y坐标的距离,但是间接过去是去中间的点的x,y距离的较小值相加。
所以每个点和多余的点建边其实没什么意义,只用和与自己在x,y相邻的点建边就行了。
那么排个序,挨个建边,跑最短路,KO
还有一个坑点,这道题卡SPFA
SPFA对于稠密图效率很低,不如dijkstra
但是它真的能逼我去写dijkstra吗???
答案是否定的
dijkstra可以堆优化,spfa一样可以。其实说是堆,我大概也不会真的手写堆吧。。。
STL里有一个优先队列priority_queue非常好用,作为一个队列可以logn维护队列有序,经常被当做堆使用。
大根堆的话直接用就行,小根堆的话就需要加一个:
priority_queue<int,vector<int>,greater<int> > xiao;
详细的话就看完整代码吧:
#include<stdio.h>#include<cstring>#include<queue>#include<map>#include<algorithm>using namespace std;typedef long long dnt;struct point{ int x,y,idx;}pt[1000010];struct edge{ int last,v,w;}ed[1000010];int num=0,n;int se[500010],head[500010];dnt dis[500010],INF=1e14+7LL;priority_queue < pair<dnt,int> ,vector< pair<dnt,int> > ,greater<pair<dnt,int> > > state;bool cmp1(const point &a,const point &b){ return a.x<b.x;}bool cmp2(const point &a,const point &b){ return a.y<b.y;}bool cmp3(const point &a,const point &b){ return a.idx<b.idx;}void add(int u,int v,int w){ num++; ed[num].v=v; ed[num].w=w; ed[num].last=head[u]; head[u]=num;}void spfa(){ for(int i=1;i<=n;i++) dis[i]=INF; state.push(make_pair(0,1)); se[1]=1,dis[1]=0; while(!state.empty()) { int u=state.top().second; state.pop(); se[u]=0; for(int i=head[u];i;i=ed[i].last) { int v=ed[i].v; if(dis[v]>dis[u]+ed[i].w) { dis[v]=dis[u]+ed[i].w; if(!se[v]) { se[v]=1; state.push(make_pair(dis[v],v)); } } } }}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&pt[i].x,&pt[i].y); pt[i].idx=i; } sort(pt+1,pt+n+1,cmp1); for(int i=1;i<n;i++) { add(pt[i].idx,pt[i+1].idx,pt[i+1].x-pt[i].x); add(pt[i+1].idx,pt[i].idx,pt[i+1].x-pt[i].x); } sort(pt+1,pt+n+1,cmp2); for(int i=1;i<n;i++) { add(pt[i].idx,pt[i+1].idx,pt[i+1].y-pt[i].y); add(pt[i+1].idx,pt[i].idx,pt[i+1].y-pt[i].y); } spfa(); printf("%lld",dis[n]); return 0; }
嗯,就是这样
阅读全文
0 0
- BZOJ 4152 浅谈堆优化的SPFA算法
- BZOJ 2763 JLOI2011 飞行路线 分层图+堆优化SPFA
- BZOJ 1179 APIO2009 ATM Tarjan+堆优化SPFA
- spfa算法的一些优化
- SPFA算法的两个优化
- 堆优化SPFA
- SPFA 堆优化模板
- EOJ 1848 你是ACM吗? 用二叉堆优化dijkstra + spfa算法的学习
- bellman-ford算法的优化spfa算法
- spfa算法(FIFO优化的BellmanFord算法)
- BZOJ 3627 JLOI2014 路径规划 分层图+堆优化SPFA JLOI2014全AC达成!
- spfa的SLF 和 LLL优化算法
- Candies POJ 3159 (堆优化的SPFA,)
- SPFA算法 Bellman_ford优化
- 堆优化的Dijkstra算法
- prim算法的堆优化。
- 堆优化的prim算法
- POJ 1511 Invitation Cards 【最短路,spfa算法,Dijkstra算法堆优化】
- 实验DG 跳归档恢复
- 【NOIP2016提高A组模拟7.21】Double-row
- 关于httpwatch安装之后在IE浏览器找不到加载项的解决办法
- [IOS APP]闯关东-百年长卷有声版
- Leetcode题解
- BZOJ 4152 浅谈堆优化的SPFA算法
- SharePoint REST API
- 55. Jump Game
- 2017 DPDK summit 主讲美团云&OVS-DPDK
- 新理解:反射+Java值传递+序列化
- 解决页面请求/响应中文乱码问题
- linux启动了大量的httpd进程,占用大量内存
- codeforces 822 My pretty girl Noora(递推)
- treeList节点过滤