题目链接: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在文本框之后添加红*

    var addHtml="<span class='text_red'>*</span>";function req(re){ if(re.parent(& ...

  2. objective-c訪问控制符

    objective-c中成员变量的四个訪问控制符: @private:仅仅有当前类的内部才干訪问 @public:全部人都可訪问 @protected:仅仅限当前类和它的子类可以訪问 @package ...

  3. linux /proc/cpuinfo 文件描写叙述

    processor :系统中逻辑处理核的编号.对于单核处理器.则课觉得是其CPU编号,对于多核处理器则能够是物理核.或者使用超线程技术虚拟的逻辑核 vendor_id :CPU制造商 cpu fami ...

  4. Android DatePickerDialog样式不一致的问题

    三星和华为的平板上,DatePickerDialog的显示样式不一致.三星的仅仅显示月日年选择框,而华为的平板上另外还显示了日历表.代码同样. 可能是系统控件做了部分改动,后来你发现是能够设置的: D ...

  5. 数据库中的java.sql.Timestamp转换成Date

    查询数据库中的时间类型为 java.sql.Timestamp 保存在json中需要格式化 自定义工具类  DateJsonValueProcessor package com.rom.util; i ...

  6. 【Linux驱动】TQ2440 DM9000E网卡驱动移植(Linux-2.6.30.4)

    花了一天的时间研究了一下Linux-2.6.30.4版本号内核下关于TQ2440 DM9000E的网卡驱动移植.总结一下自己的收获. 事实上.在Linux-2.6.30.4版本号内核下有关于网卡驱动, ...

  7. ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用!因此,ES transport client可以同步调用也可以异步(不过底层的socket必然是异步实现)

    ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用! 因此,ES tra ...

  8. 高级程序员与CTO技术总监首席架构师

    一.高级程序员 如果你是一个刚刚创业的公司,公司没有专职产品经理和项目经理,你就是公司的产品经理,你如果对你现在的开发员能力不满,那么你只需要的是一个高级程序员. 你定义功能.你做计划推进和管理,他可 ...

  9. 133.throw机制 抛出类类型

    #include <iostream> using namespace std; //try尝试执行,抛出throw,throw之后语句不再执行 //catch处理throw的异常 voi ...

  10. 移动端fixed后 横竖屏切换时上部或下部出现空隙问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...