BZOJ.4289.PA2012 Tax(思路 Dijkstra)
\(Description\)
给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价。起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边权。
\(Solution\)
最直接的方法是把每条边作为一个点,对于连接同一个点的两条边连一条新边,最后把连接1和n的点分别连S、T,跑最短路
但这样边数是O(m^2)的
对于路径上相邻两条边\((i,j,v1)\)和\((j,k,v2)\),v1<v2,考虑如何构图把v1比v2小的部分补上
那么对于点j拆点,每个点对应一条出边或入边,按边权排序,设相邻两点对应权值为v1,v2(v1<v2),那么建边\((j',j,0)\),\((j,j',v2-v1)\)
最后起点处的代价没有被计算,在起点的每条出边加上一个点即可
复杂度O(mlogm)
很像的边表边很容易写错。。
不会写代码。。
没有边权范围要longlong

//35772kb 1892ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define pr std::pair<LL,int>
#define mp std::make_pair
typedef long long LL;
const int N=4e5+5,M=4e5+5,MAXIN=3e6;//N:两倍边数
const LL INF=1ll<<60;
int src,des,n,m,Enum,H[N],nxt[M<<2],to[M<<2],val[M<<2],tmp[M];//边数一直错。。mdzz 开始一共4e5条边
int num,h[N>>1],tto[M],tnxt[M],tval[M];
LL dis[N];
bool vis[N];
char IN[MAXIN],*SS=IN,*TT=IN;
std::priority_queue<pr> q;
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
inline bool cmp(int i,int j) {return tval[i]<tval[j];}
inline void Add(int u,int v,int w){
tto[++num]=v, tnxt[num]=h[u], tval[num]=w, h[u]=num;
}
inline void AddEdge(int u,int v,int w){
to[++Enum]=v, nxt[Enum]=H[u], val[Enum]=w, H[u]=Enum;
}
void Build()
{
src=1, des=(m+1)<<1;
for(int i=1; i<=n; ++i)
{
int cnt=0;
for(int j=h[i]; j; j=tnxt[j])
tmp[++cnt]=j;//存编号就行了
std::sort(tmp+1,tmp+1+cnt,cmp);
for(int now,next,j=1; j<=cnt; ++j)//~
{
now=tmp[j], next=tmp[j+1];//直接拿边号来建就可以了 也是建的双向边
if(i==1) AddEdge(src,now,tval[now]);//把连向src的边拆出一个点来
if(tto[now]==n) AddEdge(now,des,tval[now]);
AddEdge(now^1,now,tval[now]);//只建一条边 还有另一个点的边
if(j<cnt) AddEdge(now,next,tval[next]-tval[now]), AddEdge(next,now,0);
}
// if(cnt) AddEdge(tmp[cnt]^1,tmp[cnt],tval[tmp[cnt]]);//WA!没有上面两个条件特判!
}
}
LL Dijkstra()
{
for(int i=src+1; i<=des; ++i) dis[i]=INF;
dis[src]=0, q.push(mp(0,src));
while(!q.empty())
{
int x=q.top().second; q.pop();
if(vis[x]) continue;
if(x==des) return dis[x];
vis[x]=1;
for(int v,i=H[x]; i; i=nxt[i])
if(!vis[v=to[i]] && dis[v]>dis[x]+val[i])
dis[v]=dis[x]+val[i], q.push(mp(-dis[v],v));
}
return dis[des];
}
int main()
{
n=read(),m=read();
num=1;
for(int u,v,w,i=1; i<=m; ++i)
u=read(),v=read(),w=read(),Add(u,v,w),Add(v,u,w);
Build();
printf("%lld",Dijkstra());
return 0;
}
BZOJ.4289.PA2012 Tax(思路 Dijkstra)的更多相关文章
- BZOJ 4289: PA2012 Tax Dijkstra + 查分
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- ●BZOJ 4289 PA2012 Tax
●赘述题目 算了,题目没有重复的必要. 注意理解:对答案造成贡献的是每个点,就是了. 举个栗子: 对于如下数据: 2 1 1 2 1 答案是 2: ●题解 方法:建图(难点)+最短路. 先来几个链接: ...
- bzoj 4289: PA2012 Tax
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- 【刷题】BZOJ 4289 PA2012 Tax
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- BZOJ 4289: PA2012 Tax 差分建图 最短路
https://www.lydsy.com/JudgeOnline/problem.php?id=4289 https://www.cnblogs.com/clrs97/p/5046933.html ...
- bzoj 4289 PA2012 Tax——构图
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 可以把一个点上的边按权值排序,然后边权小的向第一个比它大的连差值的边,边权大的向第一个 ...
- BZOJ 4289: PA2012 Tax(最短路)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 755 Solved: 240[Submit][Status][Discuss] Descriptio ...
- [Bzoj4289]PA2012 Tax(Dijkstra+技巧建图)
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- [BZOJ4289] [PA2012] Tax 解题报告 (最短路+差分建图)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 4289: PA2012 Tax Time Limit: 10 Sec Memo ...
随机推荐
- 记一次Win Server 2012部署问题及解决方法
1.前言 本章内容为在win server 2012服务器部署时遇到的问题及解决方法.大致工作为:两台服务器,一台web.一台数据库:web服务器部署.net web程序,数据库服务器安装oracle ...
- Python基础-封装与扩展、静态方法和类方法
一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数)名.参数不变,使用者的代码永远无需改变.这就提供一个 ...
- C语言中,float在内存中的储存方式
浮点型变量在计算机内存中占用4字节(Byte),即32-bit. 遵循IEEE-754格式标准. 一个浮点数由2部分组成:底数m 和 指数e. ±mantissa × 2exponent (注意,公式 ...
- Linux: 介绍make menuconfig中的每个选项含义【转】
转自:http://blog.csdn.net/gaoyuanlinkconcept/article/details/8810468 介绍make menuconfig中的每个选项含义 Linux 2 ...
- Android数据存储:File
Android数据存储之File Files:它通过FileInputStream和FileOuputStream对文件进行操作.但是在Android中,文件是一个应用程序私有的,一个应用程序无法读写 ...
- 基于Apache的阿里云部署Node.js服务器(Windows环境)
1 前言 由于nodejs项目对方开放了多个端口,而且阿里云上的Apache服务器(windows)已经挂载了网站,此时需要把此项目也挂上去,网上查询资料,方法略少,基本是基于nginx版本的. 2 ...
- JQuery 插件一般方法
如今做web开发,jquery 几乎是必不可少的,就连vs神器在2010版本开始将Jquery 及ui 内置web项目里了.至于使用jquery好处这里就不再赘述了,用过的都知道.今天我们来讨论下jq ...
- PHP 将数组的值赋值给一组变量
经常需要将一个字符串分割成一组值,然后赋值给不同的变量. 逐行赋值非常繁琐,于是查了一下 PHP 中是否有类似 python 中 a, b = (a, b) 的操作. 果然有 $info = arra ...
- ORACLE 锁表处理,解锁释放session
后台数据库操作某一个表时发现一直出于假死状态,可能是该表被某一用户锁定,或者后台数据库操作某一个表时发现一直出于"假死"状态,可能是该表被某一用户锁定,导致其他用户无法继续操作 - ...
- pika的阻塞式使用
[root@cloudplatform ELK]# cat startIncHouTai.py import os # 杀掉内存中的进程 cmd='pgrep -f PutDataToKafkaInc ...