差分优化建边(Tax)
[Luogu P6822PA2012]Tax] (http://www.luogu.com.cn/problem/P6822")
All right. Let's go!
- 题目描述
给出一个 n 个点 m 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 1 到点 n 的最小代价。起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边权。
这感觉非常棘手啊,这道题弯很多,首先不考虑连边建图,这道题该如何下手。
猜一猜:最短路算法是肯定的
可是在图论中通常是“ 停在点,经过边 ”,可这里是“ 经过点 ! ”,有没有一种反过来的感觉。
我们就用到了一种(类物理)的转换法
边点颠倒: 将边化为点,点化为边(连边时直接连存下来的边的编号即可)
但是直接这么连还是会超时,所以考虑连边建图
把无向边拆解为两条有向边
对于每个点,有几条进入它的入边,同样也有几条它延出的出边。我们按他们的边权从小到大排序
1.每条入边连相同所至点出边
2.而出边中,从前到后,E[i]->E[i+1] 权值为 E[i+1]-E[i] 反过来E[i+1]->E[i]权值为0
这里排序后,利用了差分 的思想
代码有点繁杂:
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=5e6+5;
typedef long long ll;
ll dis[N],Len[N];
int n,m,Tot,cnt,Nxt[N],To[N],Head[N];
bool mark[N];
struct node {
int num;ll w;
bool operator<(const node u) const{
return w<u.w;
}
};
vector<node> G[100005];
void add_edge(int u,int v,ll w) {
Tot++; Nxt[Tot]=Head[u]; Len[Tot]=w; To[Tot]=v; Head[u]=Tot;
}
struct Node {
int p;ll w;
bool operator<(const Node u) const{
return w>u.w;
}
};
priority_queue<Node> Q;
void DJ(int s) {
dis[s]=0;
Q.push((Node){s,0});
while(!Q.empty()) {
int u=Q.top().p; Q.pop();
if(mark[u]) continue;
mark[u]=true;
for(int i=Head[u];i;i=Nxt[i]) {
int v=To[i];
if(!mark[v]&&dis[v]>dis[u]+Len[i]) {
dis[v]=dis[u]+Len[i];
Q.push((Node){v,dis[v]});
}
}
}
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) {
int u,v; ll w;
scanf("%d%d%lld",&u,&v,&w);
G[u].push_back((node){i*2-1,w});
G[v].push_back((node){i*2,w}); //相邻的一条互为反向边
}
for(int i=1;i<=n;i++) {
sort(G[i].begin(),G[i].end());
}
for(int sz=G[1].size(),j=0;j<sz;j++) {
int v2=G[1][j].num,v1;
if(v2&1) v1=v2+1; else v1=v2-1;
add_edge(0,v2,G[1][j].w);
}
for(int i=2;i<n;i++) {
for(int sz=G[i].size(),j=0;j<sz;j++) {
int v2=G[i][j].num,v1; ll w=G[i][j].w;
if(v2&1) v1=v2+1; else v1=v2-1;
add_edge(v1,v2,w);
if(j) {
add_edge(G[i][j-1].num,v2,w-G[i][j-1].w);
add_edge(v2,G[i][j-1].num,0);
}
}
}
for(int sz=G[n].size(),j=0;j<sz;j++) {
int v2=G[n][j].num,v1;
if(v2&1) v1=v2+1; else v1=v2-1;
add_edge(v1,m*2+1,G[n][j].w);
// printf("%d %d %d\n",v.num,m*2+1,v.w);
}
memset(dis,0x3f,sizeof(dis));
DJ(0);
printf("%lld",dis[m*2+1]);
return 0;
}
差分优化建边(Tax)的更多相关文章
- 【bzoj4383】[POI2015]Pustynia 线段树优化建图+差分约束系统+拓扑排序
题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r- ...
- [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)
[Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...
- UOJ#77. A+B Problem [可持久化线段树优化建边 最小割]
UOJ#77. A+B Problem 题意:自己看 接触过线段树优化建图后思路不难想,细节要处理好 乱建图无果后想到最小割 白色和黑色只能选一个,割掉一个就行了 之前选白色必须额外割掉一个p[i], ...
- [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增
题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...
- [SDOI2017]天才黑客[最短路、前缀优化建图]
题意 一个 \(n\) 点 \(m\) 边的有向图,还有一棵 \(k\) 个节点的 trie ,每条边上有一个字符串,可以用 trie 的根到某个节点的路径来表示.每经过一条边,当前携带的字符串就会变 ...
- Codeforces 1045. A. Last chance(网络流 + 线段树优化建边)
题意 给你 \(n\) 个武器,\(m\) 个敌人,问你最多消灭多少个敌人,并输出方案. 总共有三种武器. SQL 火箭 - 能消灭给你集合中的一个敌人 \(\sum |S| \le 100000\) ...
- BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan
Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...
- cf786E ALT (最小割+倍增优化建图)
如果把“我全都要”看作是我全不要的话,就可以用最小割解决啦 源点S,汇点T 我们试图让每个市民作为一个等待被割断的路径 把狗狗给市民:建边(S,i,1),其中i是市民 把狗狗给守卫:建边(j,T,1) ...
- 【LibreOJ】#6354. 「CodePlus 2018 4 月赛」最短路 异或优化建图+Dijkstra
[题目]#6354. 「CodePlus 2018 4 月赛」最短路 [题意]给定n个点,m条带权有向边,任意两个点i和j还可以花费(i xor j)*C到达(C是给定的常数),求A到B的最短距离.\ ...
随机推荐
- 基 vue-element-admin升级的Vue3 +TS +Element-Plus 版本的后端管理前端解决方案 vue3-element-admin 正式对外发布,有来开源组织又一精心力作,毫无保留开放从0到1构建过程
项目简介 vue3-element-admin 是基于 vue-element-admin 升级的 Vue3 + Element Plus 版本的后台管理前端解决方案,是 有来技术团队 继 youla ...
- prometheus之查询语言
PromQL(Prometheus Query Language)是 Prometheus 自己开发的表达式语言,语言表现力很丰富,内置函数也很多.使用它可以对时序数据进行筛选和聚合. 一.PromQ ...
- Mybatis 实现批量插入和批量删除源码实例
Mybatis 实现批量插入数据和批量删除数据 学习内容: 准备工作 1.数据库新建表 2.新建 Maven 项目和设置编译版本及添加依赖 3.新建 db.properties 4.新建 mybati ...
- Wireshark查找与标记数据包
查找数据包 按Ctrl-F. 查找数据包提供了4个选项: 显示过滤器(Display filter):该选项可以让你通过输入表达式进行筛选,并只找出那些满足该表达式的数据包.如:not ip, ip. ...
- pycharm——import已存在的库居然失败!
问题 明明在cmd中可以import的库,放到pycharm中却找不到. 问题根源 找了一圈,最后得到这个结论. 因为pycharm默认就是这样的... 解决 打开设置,找到解释器 点击右边齿轮图标, ...
- OllyDbg---比较、条件跳转指令
比较和条件跳转 CMP 比较两个操作数,相当于SUB指令,但是相减的结果不保存到第一个操作数,而是根据相减的结果来改变零标志位.当两个操作数相等时,零标志位Z置为1. 两个操作数不相等时,零标志位Z被 ...
- 服务器jupyter连接不上主机
首先安装jupyter pip3 install jupyter -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com 然后 ...
- 小米手环解锁MacOS系统笔记本MacBookPro
通过小米手环解锁笔记本 官方windows是提供了方法的. 我目前用的MacBookPro,所以说下苹果笔记本的解锁方式. 安装软件BLEUnlock 库 安装方式: brew 安装 brew ins ...
- 安卓记账本开发学习day5之版本兼容问题
安卓5.0以上版本想要隐藏DatePicker头布局的写法比较复杂,需要一层一层隐藏 int headerId = getContext().getResources().getIdentifier( ...
- Java语言学习day18--7月24日
###01get和set方法 * A.get和set方法 * 年龄已被私有,错误的值无法赋值,可是正确的值也赋值不了,这样还是不行,那肿么办呢?按照之前所学习的封装的原理,隐藏后,还需要提供访问方式. ...