Description

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

Input

Output

那个取最大值的操作十分烦人,考虑如何将这个判断去掉.
可以用查分的方式:如果进来的边是小的,那么从大的边出去就要补齐差值.
补齐差值就直接连一条差值为 $d$ 的边即可.
然后跑一个 $Dijkstra$ 即可.

#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#include <map>
#define N 400003
#define inf 10000000000000
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
namespace IO
{
char *p1, *p2, buf[100000]; #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ ) int rd() {
int x = 0, f = 1;
char c = nc();
while (c < 48) {
if (c == '-')
f = -1;
c = nc();
}
while (c > 47) {
x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
}
return x * f;
}
};
struct Edge
{
int to,dis;
Edge(int to=0,int dis=0):to(to),dis(dis){}
};
vector<Edge>G[N];
bool cmp(Edge a,Edge b)
{
return a.dis<b.dis;
}
map<int,int>id[N];
int n,m,cnt,edges,s,t;
int hd[N*6],nex[N*6],to[N*6],done[N*6];
ll d[N*6],val[N*6];
inline void addedge(int u,int v,int c)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=1ll*c;
}
struct Node
{
ll dis;
int u;
Node(ll dis=0,int u=0):dis(dis),u(u){}
bool operator<(Node b) const
{
return dis>b.dis;
}
};
priority_queue<Node>q;
inline void Dijkstra()
{
int i;
for(i=0;i<=t;++i) d[i]=inf, done[i]=0;
d[s]=0, q.push(Node(0,s));
while(!q.empty())
{
Node e=q.top();q.pop();
if(done[e.u]) continue;
done[e.u]=1;
int u=e.u;
for(i=hd[u];i;i=nex[i])
{
int v=to[i];
if(d[u]+val[i]<d[v])
{
d[v]=d[u]+val[i];
q.push(Node(d[v],v));
}
}
}
}
int main()
{
int i,j;
// setIO("input");
n=IO::rd(),m=IO::rd();
for(i=1;i<=m;++i)
{
int a=IO::rd(),b=IO::rd(),c=IO::rd();
G[a].push_back(Edge(b,c)), G[b].push_back(Edge(a,c));
}
for(i=1;i<=n;++i)
{
sort(G[i].begin(),G[i].end(),cmp);
if(G[i].empty()) continue;
id[i][G[i][0].dis]=++cnt;
for(j=1;j<(int)G[i].size();++j) if(G[i][j].dis!=G[i][j-1].dis) id[i][G[i][j].dis]=++cnt;
}
for(i=1;i<=n;++i)
{
int k,lst=0,pre=0;
for(k=0;k<(int)G[i].size();k=j+1)
{
j=k;
int cur=id[i][G[i][j].dis];
while(j<(int)G[i].size()-1&&G[i][j+1].dis==G[i][j].dis) ++j;
if(lst) addedge(cur,lst,0), addedge(lst,cur,G[i][k].dis-pre);
for(int o=k;o<=j;++o) addedge(cur, id[G[i][o].to][G[i][o].dis], G[i][o].dis);
lst=cur, pre=G[i][k].dis;
}
}
s=0, t=cnt+2;
for(i=0;i<G[1].size();++i) if(i==0||G[1][i].dis!=G[1][i-1].dis) addedge(s,id[1][G[1][i].dis],G[1][i].dis);
for(i=0;i<G[n].size();++i) if(i==0||G[n][i].dis!=G[n][i-1].dis) addedge(id[n][G[n][i].dis],t,0);
Dijkstra(), printf("%lld\n",d[t]);
return 0;
}

  

BZOJ 4289: PA2012 Tax Dijkstra + 查分的更多相关文章

  1. BZOJ.4289.PA2012 Tax(思路 Dijkstra)

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

  2. bzoj 4289: PA2012 Tax

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

  3. ●BZOJ 4289 PA2012 Tax

    ●赘述题目 算了,题目没有重复的必要. 注意理解:对答案造成贡献的是每个点,就是了. 举个栗子: 对于如下数据: 2 1 1 2 1 答案是 2: ●题解 方法:建图(难点)+最短路. 先来几个链接: ...

  4. 【刷题】BZOJ 4289 PA2012 Tax

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

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

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

  6. bzoj 4289 PA2012 Tax——构图

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 可以把一个点上的边按权值排序,然后边权小的向第一个比它大的连差值的边,边权大的向第一个 ...

  7. BZOJ 4289: PA2012 Tax(最短路)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 755  Solved: 240[Submit][Status][Discuss] Descriptio ...

  8. [BZOJ4289] [PA2012] Tax 解题报告 (最短路+差分建图)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 4289: PA2012 Tax Time Limit: 10 Sec  Memo ...

  9. 「BZOJ 4289」 PA2012 Tax

    「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...

随机推荐

  1. python 并发编程 多线程 GIL与多线程

    GIL与多线程 有了GIL的存在,同一时刻同一进程中只有一个线程被执行 多进程可以利用多核,但是开销大,而python的多线程开销小,但却无法利用多核优势 1.cpu到底是用来做计算的,还是用来做I/ ...

  2. 暴力破解-H3C路由器-MSR900

    作者:zptxwd@gmail.com  最后修改日期2017年5月10日    转载请保留出处 声明,本文仅用于技术交流和学习,不得用于任何商业用途及违法行为.   所暴力破解的设备信息 华三路由器 ...

  3. Spring(八)-- 代理设计模式

    代理设计模式 1:基本概念 2:JDK动态代理 1. 创建接口 2. 创建实现类 3. 创建代理类 /** * jdk动态代理 不能满足 继承父类的情况 * * AnimalProxy 代理类 */ ...

  4. java--编码规范易漏

    1:命名规范 类名用大驼峰式 参数变量·函数·成员变量·局部变量 小驼峰式 常亮命名全部大些单词用_隔开 抽象类用Abstract开头·异常类用Excetpion结尾·测试类用Test结尾 *POJO ...

  5. Ehcache 入门详解 (转)

    一:目录 EhCache 简介 Hello World 示例 Spring 整合 二: 简介 2.1.基本介绍 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hiberna ...

  6. AQS之Condition

    一.引言 一般我们在使用锁的Condition时,我们一般都是这么使用,以ReentrantLock为例, ReentrantLock lock = new ReentrantLock(); Cond ...

  7. Vue.js实现分页

    效果图 代码 <!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/ ...

  8. phpmyadmin导入大容量.sql文件

    phpmyadmin导入大容量.sql文件 在phpmyadmin目录文件夹下建立一个文件夹,如importSqlFile 将想要导入的sql文件放入importSqlFile文件夹中 打开confi ...

  9. c#委托(Delegates)--基本概念及使用

    在我这菜鸟理解上,委托就是可以用方法名调用另一方法的便捷方法,可以简化switch等语句的重复.最近做项目的时候恰好需要用到委托,便来复习及学习委托的使用.嗯...本人以前并没有用过,只是稍微知道而已 ...

  10. 机器学习-非线性回归(Logistic Regression)及应用

    1. 概率 1.1 定义:概率(Probability):对一件事情发生的可能性的衡量. 1.2 范围:0 <= P <= 1 1.3 计算方法: 1.3.1 根据个人置信 1.3.2 根 ...