差分优化建边(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的最短距离.\ ...
随机推荐
- 移动端城市定位,城市区域代码adcode
使用高德定位API : AMap.Map('iCenter') AMap.CitySearch() 先在高德开放平台注册申请定位权限的key. 网站:高德开放平台 在需要定位的页面引入有定位key的s ...
- java中请给出例子程序:找出两个数的最大公约数和最小公倍数
9.2 找出12和8的最大公约数和最小公倍数. public class Test { public static void main(String[] args) { ...
- java如何读取和遍历properties文件
在java项目开发过程中,使用properties文件作为配置基本上是必不可少的,很多如系统配置信息,文件上传配置信息等等都是以这种方式进行保存.同时学会操作properties文件也是java基础. ...
- JS判断数组中的对象的每一个值不能为空
方法一:使用every()函数,此函数不怎么常用,想要了解更多请自查 //表格 evaluateData为表格的数据 <el-table id="out-table3" :d ...
- 拼凑一个ABP VNext管理后台
介绍 本项目前后端分离,后端采用ABP VNext框架,前端Vue. 项目地址: https://github.com/pojianbing/AuthCenter 目前包含的模块有: 身份认证管理 I ...
- JAVASE Scanner
package com.huang.boke.flowPath;import java.util.Scanner;public class test01 { public static void ma ...
- python---运算符和编码
格式化输出 在输出数据时,会有用户需要输入的信息被输出,没办法预先知道,这就需要使用格式化输出.先在相应位置放置一个占位符,再把字符串里的占位符与外部的变量做个映射关系. name = input(& ...
- SSM实现个人博客-day01
1.需求分析 项目源码免费下载:SSM实现个人博客 有问题请询问vx:kht808
- docker基础容器中bash: vi: command not found问题解决
安装即可 1.apt-get update 2.apt-get install vim
- Linux下安装Typora
系统:Ubuntu16.0 下载链接:https://www.typora.io/#linux 参考链接:https://www.cnblogs.com/wenkangzero/p/13202415. ...