博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bzoj4289: PA2012 Tax
阅读量:5929 次
发布时间:2019-06-19

本文共 2393 字,大约阅读时间需要 7 分钟。

题面

Sol

巧妙的建图+\(Dijkstra\)

考虑把边看成点,那么显然暴力建图的边数是\(m^2\)
考虑优化
\(max(a, b)\)变成\(a+max(b-a,0)\)
把每个点连出的边按权值从小到大排序
每个边向后面的边连\(b-a\), 后面向前面连\(0\)
连向它的边向连出去的边连\(a\)
新建\(S\)点,向\(1\)连出的边连,新建\(T\),连向\(n\)的边连\(T\)

没开long long WA一片

# include 
# define RG register# define IL inline# define Fill(a, b) memset(a, b, sizeof(a))using namespace std;typedef long long ll;const int _(4e5 + 5);typedef int Arr[_]; IL int Input(){ RG int x = 0, z = 1; RG char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1; for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48); return x * z;} Arr first, vis;ll dis[_];int n, m, cnt, S, T;struct Data{ int u; ll dis; IL int operator <(RG Data B) const{ return dis > B.dis; }};priority_queue
Q;struct Edge{ int to, next, w;} edge[_ << 2];struct Link{ int v, w, id; IL int operator <(RG Link B) const{ return w < B.w; }};vector
G[_];IL void Add(RG int u, RG int v, RG int w){ edge[cnt] = (Edge){v, first[u], w}, first[u] = cnt++;} IL void Dijkstra(){ Fill(dis, 63), dis[S] = 0, Q.push((Data){S, 0}); while(!Q.empty()){ RG Data x = Q.top(); Q.pop(); if(vis[x.u]) continue; vis[x.u] = 1; for(RG int e = first[x.u]; e != -1; e = edge[e].next){ RG int v = edge[e].to, w = edge[e].w; if(dis[x.u] + w < dis[v]) Q.push((Data){v, dis[v] = dis[x.u] + w}); } }} int main(RG int argc, RG char *argv[]){ Fill(first, -1), n = Input(), m = Input(); for(RG int i = 1; i <= m; ++i){ RG int u = Input(), v = Input(), w = Input(); G[u].push_back((Link){v, w, i}); G[v].push_back((Link){u, w, m + i}); } T = m + m + 1; RG int tmp = m; for(RG int i = 1; i <= n; ++i){ sort(G[i].begin(), G[i].end()); RG int l = G[i].size(); for(RG int j = 0; j < l; ++j){ Add((G[i][j].id > tmp ? G[i][j].id - m : G[i][j].id + m), G[i][j].id, G[i][j].w); if(i == 1) Add(S, G[i][j].id, G[i][j].w); if(G[i][j].v == n) Add(G[i][j].id, T, G[i][j].w); } for(RG int j = 0; j < l - 1; ++j){ Add(G[i][j].id, G[i][j + 1].id, G[i][j + 1].w - G[i][j].w); Add(G[i][j + 1].id, G[i][j].id, 0); } } Dijkstra(); printf("%lld\n", dis[T]); return 0;}

转载于:https://www.cnblogs.com/cjoieryl/p/8663411.html

你可能感兴趣的文章
Windows Server 2008 R2 /2012 修改密码策略
查看>>
forword/ sendRediect
查看>>
SmaterWeatherApi---签名加密和数据訪问--简单粗暴一步搞定
查看>>
double保持精度,防止小数点后数字的丢失的小方法
查看>>
jmeter ---参数化
查看>>
xss绕过htmlspecialchars实体编码的姿势
查看>>
Linux学习笔记:系统启动引导过程
查看>>
由于删除DBF文件报错 —— ORA-01033: ORACLE initialization or shutdown in progress
查看>>
SQLAlchemy使用笔记--SQLAlchemy ORM(三)
查看>>
七拼八凑的读书感
查看>>
Option可选值可选值(二)
查看>>
最短路径Dijkstra算法
查看>>
设计模式之原型模式学习理解
查看>>
看不懂深度Linux系统的文件管理器图标
查看>>
印象笔记客户端的下载和安装、使用(博主推荐)
查看>>
谈抽象1——无脑copy等于自杀
查看>>
malloc 函数详解
查看>>
Windows应用程序运行权限设置
查看>>
基于霍夫变换的点云分割方法
查看>>
javascript学习(3)循环和判断
查看>>