题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4289

4289: PA2012 Tax

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1029  Solved: 310
[Submit][Status][Discuss]

Description

给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价。起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边权
N<=100000
M<=200000

Sample Input

4 5
1 2 5
1 3 2
2 3 1
2 4 4
3 4 8

Sample Output

12

                             [Submit][Status][Discuss]
 

比较有技巧的建图

首先考虑暴力点的建图:

把每条无向边拆成两条有向边.把每条边看成一个点,对于两条边a->b,b->c

在这两条边之间连有向边,边权为这两条边的权值的较大值.

新建源点S,汇点T, S向所有从1连出去的边连边,所有指向n的边向T连边. 求S->T的最短路即可.

这样的复杂度会达到O(m2)

考虑优化一下:

考虑利用差值来建边.

依然把每条边x-y拆成x->y,y->x.

枚举每个中转点x. 将x的出边按权值排序,x的每条入边向对应的出边连该边权值的边(i对应i^1)),x的每条出边向第一个比它大的出边连两边权差值的边,x的每条出边向第一个比它小的出边连权值为0的边. 新建源汇S,T S向每条1的出边连权值为该边边权的边.每条n的入边向T连该边权值的边.

仔细看图,L2>L1,发现从S到T的路径走的一定是L2,而不是L1;注意结合上述的建图过程(红色边)

跑S->T的最短路即可.

这样的复杂度是O(mlogm)就可以AC

我的SPFA被T了,估计没写错只是被卡了

以上内容部分参考DaD3zZ大佬的博客

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ll long long
using namespace std; const int N=+;
int n,m,tot1,tot2,S,T;
int head[N],h[N<<],st[N<<],vis[N<<];
ll dist[N<<];
struct EDGE
{
int to;int next;int l;
}edge[N<<],e[N<<];
inline int read()
{
char ch=getchar();
int s=,f=;
while (!(ch>=''&&ch<='')) {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
void init()
{
memset(head,-,sizeof(head));
memset(h,-,sizeof(h));
memset(dist,0x3f3f3f3f,sizeof(dist));
}
void addedge(int x,int y,int l)
{
edge[tot1]=(EDGE){y,head[x],l};
head[x]=tot1++;
}
bool cmp(int x,int y) {return edge[x].l<edge[y].l;}
void addroad(int x,int y,int l)
{
e[tot2]=(EDGE){y,h[x],l};
h[x]=tot2++;
}
void build()
{
S=*(m+)+;T=*(m+)+;
for (int i=;i<=n;i++)
{
int tp=;
for (int j=head[i];j!=-;j=edge[j].next)
st[++tp]=j;
sort(st+,st++tp,cmp);
for (int j=;j<=tp;j++)
{
int now=st[j],suc=st[j+];
if (edge[now].to==n) addroad(now,T,edge[now].l);
if (i==) addroad(S,now,edge[now].l);
addroad(now^,now,edge[now].l);
if (j<tp) {addroad(now,suc,edge[suc].l-edge[now].l);addroad(suc,now,);}
}
}
}
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q;
void Dijkstra()
{
q.push(make_pair(,S));
dist[S]=;
while (!q.empty())
{
int now=q.top().second;
ll Dis=q.top().first;q.pop();
if (Dis>dist[now]) continue;
for (int i=h[now];i!=-;i=e[i].next)
if (dist[now]+e[i].l<dist[e[i].to])
{
dist[e[i].to]=dist[now]+e[i].l;
q.push(make_pair(dist[e[i].to],e[i].to));
}
}
}
int main()
{
n=read();m=read();
init();
for (int i=;i<=m;i++)
{
int x=read(),y=read(),l=read();
addedge(x,y,l);addedge(y,x,l);
}
build();
Dijkstra();
printf("%lld\n",dist[T]);
return ;
}

[BZOJ4289] [PA2012] Tax 解题报告 (最短路+差分建图)的更多相关文章

  1. BZOJ 4289: PA2012 Tax 差分建图 最短路

    https://www.lydsy.com/JudgeOnline/problem.php?id=4289 https://www.cnblogs.com/clrs97/p/5046933.html  ...

  2. 【BZOJ-4289】Tax 最短路 + 技巧建图

    4289: PA2012 Tax Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 168  Solved: 69[Submit][Status][Dis ...

  3. [Bzoj4289]PA2012 Tax(Dijkstra+技巧建图)

    Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...

  4. 【BZOJ-4289】Tax 最短路 + 技巧建图(化边为点)

    题意 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边权N<=10 ...

  5. LOJ#6354. 「CodePlus 2018 4 月赛」最短路[最短路优化建图]

    题意 一个 \(n\) 个点的完全图,两点之间的边权为 \((i\ xor\ j)*C\) ,同时有 \(m\) 条额外单向路径,问从 \(S\) 到 \(T\) 的最短路. \(n\leq 10^5 ...

  6. [BZOJ4289][PA2012]TAX(最短路)

    首先考虑一种暴力做法,为每条边拆成两条有向边,各建一个点.若某两条边有公共点,则在边所对应的点之间连一条边,权值为两条边中的较大值.这样跑最短路是$O(m^2\log m)$的. 用类似网络流中补流的 ...

  7. BZOJ4289 : PA2012 Tax

    一个直观的想法是把每条边拆成两条有向边,同时每条有向边是新图中的一个点.对于两条边a->b与b->c,两点之间连有向边,费用为两条边费用的最大值.然后新建源点S与汇点T,由S向所有起点为1 ...

  8. bzoj4289 PA2012 Tax——点边转化

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 好巧妙的转化!感觉自己难以想出来... 参考了博客:https://blog.csdn ...

  9. 灯光照射,圆形探测类问题(解题报告)<分层差分><cmath取整>

    题目描述 一个n*n的网格图上有m个探测器,每个探测器有个探测半径r,问这n*n个点中有多少个点能被探测到. 输入输出格式 输入格式: (1<=r<n<=5000) (1<=m ...

随机推荐

  1. 电子签章盖章之jQuery插件jquery.zsign

           简介:  使用jquery.zsign可以实现电子签章盖章效果,使用方便,只需提供自己的章图片.效果图如下:        页面引用:        <link href=&quo ...

  2. linux文件与用户和群组

    文件基本属性 在图片中alogrithm的文件属性为drwxrwxr-x,其中d代表此文件为目录. 后面rwx,rwx,r-x分别代表文件所属者(ower),组(group),其他用户(other)的 ...

  3. HDU 1051: Wooden Sticks(贪心)

    Wooden Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  4. [SICP] 求值规则

    在Java语言学习中,通常不太关注求值规则. (2+4*6)*(3+5+7)这样的组合式的求值规则.通常归结为优先级问题: if.for等的求值规则通常归结为语义. 函数式编程语言的Scheme,将这 ...

  5. FireEye APT检测——APT业务占比过重,缺乏其他安全系统的查杀和修复功能

    摘自:https://zhidao.baidu.com/question/1694626564301467468.html火眼,APT威胁下快速成长 FireEye的兴起开始于2012年,这时段正好迎 ...

  6. 【App 开发框架 - App Framework】

    http://edm.mcake.com/mark/jqmboi/#plugins 官网:http://app-framework-software.intel.com/index.php 官方API ...

  7. Redis-2-对于key的通用操作

    Redis-2-对于key的通用操作 标签(空格分隔): redis del key key1 key2 作用: 删除1个或多个键 返回值: 不存在的key忽略掉,返回真正删除的key的数量 rena ...

  8. 简述Sql Server中常用的数据库对象(面试题)

    1.表(Table ) 数据库中的表与我们日常生活中使用的表格类似,它也是由行(Row) 和列(Column)组成的.列由同类的信息组成,每列又称为一个字段,每列的标题称为字段名.行包括了若干列信息项 ...

  9. Homebrew的安装及使用

    Homebrew是Mac上的软件包管理工具,能在Mac中方便的搜索安装卸载软件. 1  安装 在终端输入一下代码,回车,即可下载. ruby -e "$(curl -fsSL https:/ ...

  10. 好久不见我又回来了cnblogs

    最近一直没时间写博客.... 最近工作中遇到的问题,当时花费了一定功夫才解决. 当再次遇到,同样问题的时候,我知道自己能够解决的,但是却同样,要走原来的弯路解决他. 说到底还时确实总结啊.大概是没时间 ...