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

解法:参考https://www.cnblogs.com/zj75211/p/7168254.html这位大佬的。学到了建图新姿势。

首先还是先讲讲朴素建图:很容易想到拆点然后把边看成点,对于任意两条边a->b,b->c我们可以连一条权值为min(v1,v2)的a->c的边。容易看出这样的建图极限是n^2的,菊花图上会被卡成傻逼。我们要考虑优化建图:首先还是拆边然后把边看成点,然后我们枚举每一个中间点x(1<x<n),把x的出边按权值从小到大排序,然后小出边小大出边连权值差值的边,大出边向小出边连权值为0的边,x的每条入边向其对应的出边连权值为原边权的边,然后我们创造起点和终点:对于起点向其出边连权值原来的边,对于终点其入边向终点连权值原来的边。最后跑一次Dijkstra即可。

这样的建图看起来有些诡异,我们不妨思考一下为什么这样是对的?其实很简单:因为这样建图能起到和朴素建图一样的作用,这种方法是巧妙的利用了差值起到了一种逐步累加变成正确边长的方法。入边向相应出边的连边保证了经过x点入边的代价,然后通过补差值保证了通过x点出边的代价。并且这样累加的方式可以变成任何一条原来的边,没有任何遗漏。

只能说这样的建图确实十分巧妙,凭蒟蒻自己是想不到的,只能可遇不可求吧qwq。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,int> pii;
const int N=4e5+;
int n,m,s,t;
struct edge{ int x,y,z; }e[N<<];
vector<int> G[N]; int cnt=,head[N],nxt[N<<],to[N<<],len[N<<];
void add_edge(int x,int y,int z) {
nxt[++cnt]=head[x]; to[cnt]=y; len[cnt]=z; head[x]=cnt;
} bool cmp(int t1,int t2) { return e[t1].z<e[t2].z; } void Build() {
for (int i=;i<=*m+;i++) { //起点和终点连边
if (e[i].x==) add_edge(s,i,e[i].z);
if (e[i].y==n) add_edge(i,t,e[i].z);
}
for (int i=;i<n;i++) {
sort(G[i].begin(),G[i].end(),cmp);
for (int j=;j<G[i].size();j++) {
add_edge(G[i][j]^,G[i][j],e[G[i][j]].z); //i点入边向出边连边
if (j!=) add_edge(G[i][j],G[i][j-],); //大出边向小出边连0
if (j<G[i].size()-) //小出边向大出边连差值
add_edge(G[i][j],G[i][j+],e[G[i][j+]].z-e[G[i][j]].z);
}
}
} priority_queue<pii> q;
LL dis[N<<]; bool vis[N<<];
LL Dijkstra() {
memset(dis,0x3f,sizeof(dis));
dis[s]=;
q.push(make_pair(,s));
while (!q.empty()) {
pii u=q.top(); q.pop();
if (vis[u.second]) continue;
vis[u.second]=;
for (int i=head[u.second];i;i=nxt[i]) {
int y=to[i];
if (dis[u.second]+len[i]<dis[y]) {
dis[y]=dis[u.second]+len[i];
q.push(make_pair(-dis[y],y));
}
}
}
return dis[t];
} int main()
{
cin>>n>>m;
s=; t=m*+;
for (int i=;i<=m;i++) {
int x,y,z; scanf("%d%d%d",&x,&y,&z);
e[i*]=(edge){x,y,z};
e[i*+]=(edge){y,x,z};
G[x].push_back(i*); G[y].push_back(i*+); //G[i]保存i出边编号
}
Build();
cout<<Dijkstra()<<endl;
return ;
}

BZOJ 4289 最短路+优化建图的更多相关文章

  1. BZOJ 4276 [ONTAK2015]Bajtman i Okrągły Robin 费用流+线段树优化建图

    Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2],...,[b[i]-1,b[i]]这么多段长度为1时间中选出一个时间进行抢劫,并计划抢 ...

  2. BZOJ 3073: [Pa2011]Journeys Dijkstra+线段树优化建图

    复习一下线段树优化建图:1.两颗线段树的叶子节点的编号是公用的. 2.每次连边是要建两个虚拟节点 $p1,p2$ 并在 $p1,p2$ 之间连边. #include <bits/stdc++.h ...

  3. bzoj3073: [Pa2011]Journeys 线段树优化建图

    bzoj3073: [Pa2011]Journeys 链接 BZOJ 思路 区间和区间连边.如何线段树优化建图. 和单点连区间类似的,我们新建一个点,区间->新点->区间. 又转化成了单点 ...

  4. 【BZOJ4383】[POI2015]Pustynia 线段树优化建图

    [BZOJ4383][POI2015]Pustynia Description 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r ...

  5. AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图

    AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ...

  6. loj#2255. 「SNOI2017」炸弹 线段树优化建图,拓扑,缩点

    loj#2255. 「SNOI2017」炸弹 线段树优化建图,拓扑,缩点 链接 loj 思路 用交错关系建出图来,发现可以直接缩点,拓扑统计. 完了吗,不,瓶颈在于边数太多了,线段树优化建图. 细节 ...

  7. bzoj4383 [POI2015]Pustynia 拓扑排序+差分约束+线段树优化建图

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4383 题解 暴力的做法显然是把所有的条件拆分以后暴力建一条有向边表示小于关系. 因为不存在零环 ...

  8. BZOJ-3495 前缀优化建图2-SAT

    题意:有n个城镇被分成了k个郡,有m条连接城镇的无向边.要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都. 解法:以前没学过,参考https://blog.csdn.net/linkf ...

  9. codeforces 787D - Legacy 线段树优化建图,最短路

    题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...

随机推荐

  1. 面试题:实现call、apply、bind

    面试题:实现call.apply.bind 实现bind module.exports = function(Tcontext, ...args) { let globalThis = typeof ...

  2. WPF自适应问题

    引用水哥同事的文章 点击跳转

  3. ubuntu 安装 docker

    安装命令 sudo apt-get update sudo apt-get install docker.io 启动docker后台服务 sudo service docker start 1.删除镜 ...

  4. Linux系统测试端口连通性的方法

    Linux系统测试端口连通性的方法 有四种常用方法:1. telnet 方法2. wget 方法3. ssh 方法4. curl 方法 下面一一介绍. 1. telnet用法: telnet ip p ...

  5. 笔记78 HttpStatus

    HttpStatus = { //Informational 1xx 信息 '100' : 'Continue', //继续 '101' : 'Switching Protocols', //交换协议 ...

  6. 静态部署TOMCAT

    常见部署方式:静态部署和容器化部署 一.下载tomcat安装包 下载地址:https://tomcat.apache.org/download-90.cgi 图上是显示最新版本,而我下载的是9.0.8 ...

  7. delphi 删除文件夹里面的所有文件

    1.新增一个函数 function TForm1.DelDirAll(aDir: string): Boolean;varvSearch: TSearchRec;vRet: integer;vKey: ...

  8. python3 实现堡垒机功能(并发执行命令及上传下载文件)

    转载请注明出处,欢迎提出宝贵意见,谢谢! 功能介绍: 1.主机分组 登录后显示分组主机及主机数量 选择主机组后显示该主机组下所有主机信息,主机名及IP显示输入选择:1.执行命令利用线程并发组内所有主机 ...

  9. 适配器模式Adapter

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11401410.html 1. 定义将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接 ...

  10. Python--字符编码、文字处理、函数

    了解字符编码的知识储备 我们日常用到的文本编辑器有nodepad++,pycharm,word等等,用他们存取文件的过程大致类似,需要知道打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编 ...