Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 755  Solved: 240
[Submit][Status][Discuss]

Description

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

Input

 

Output

 

Sample Input

4 5
1 2 5
1 3 2
2 3 1
2 4 4
3 4 8

Sample Output

12

HINT

Source

这题居然卡long long,也是没谁了

首先一个很显然的思路是暴力拆边

即把每个点每一条入边和每一条出边的两两看做一个点,权值为两边的较大值

但是这样很显然是$O(m^2)$,肯定会GG

所以我们考虑一种神仙操作。

对于一条无向边,我们把它看成两条有向边

然后我们这样构图

1.对于一个点,我们把它的出边从小到大排序

2.枚举每一条边,如果这条边连接着1或者N,那么我们从S连向这条边或者从这条边连向T,权值为该边的权值

3.从改边所对应的入边向该边连一条边,边权为它们的权值

4.枚举每一条出边,从权值较小的向权值较大的连权值为两边差值的边,从权值较大的向权值较小的连权值为0的边

可能这样说不是很清楚,借鉴一下这位大佬的图

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<queue>
  4. #include<cstring>
  5. #define Pair pair<long long,int>
  6. #define F first
  7. #define S second
  8. const int MAXN=*1e6+;
  9. using namespace std;
  10. inline int read()
  11. {
  12. char c=getchar();int x=,f=;
  13. while(c<''||c>''){if(c=='-')f=-;c=getchar();}
  14. while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
  15. return x*f;
  16. }
  17. struct Edge
  18. {
  19. int u,v,w,nxt;
  20. }E[MAXN];
  21. int headE[MAXN],numE=;
  22. inline void add_edge(int x,int y,int z)
  23. {
  24. E[numE].u=x;
  25. E[numE].v=y;
  26. E[numE].w=z;
  27. E[numE].nxt=headE[x];
  28. headE[x]=numE++;
  29. }
  30. struct node
  31. {
  32. int u,v,w,nxt;
  33. }edge[MAXN];
  34. int head[MAXN],num=;
  35. inline void AddEdge(int x,int y,int z)
  36. {
  37. edge[num].u=x;
  38. edge[num].v=y;
  39. edge[num].w=z;
  40. edge[num].nxt=head[x];
  41. head[x]=num++;
  42. }
  43. int N,M,S,T;
  44. int temp[MAXN];
  45. long long dis[MAXN];
  46. bool vis[MAXN];
  47. void Dijstra()
  48. {
  49. memset(dis,0xf,sizeof(dis));dis[S]=;
  50. priority_queue<Pair>q;
  51. q.push(make_pair(,S));
  52. while(q.size()!=)
  53. {
  54. while(vis[q.top().second]&&q.size()>) q.pop();
  55. long long p=q.top().second;
  56. vis[p]=;
  57. for(int i=head[p];i!=-;i=edge[i].nxt)
  58. if(dis[edge[i].v]>dis[p]+edge[i].w)
  59. dis[edge[i].v]=dis[p]+edge[i].w,
  60. q.push(make_pair(-dis[edge[i].v],edge[i].v));
  61. }
  62. printf("%lld\n",dis[T]);
  63. }
  64. int comp(const int &a,const int &b)
  65. {
  66. return E[a].w<E[b].w;
  67. }
  68. int main()
  69. {
  70. #ifdef WIN32
  71. freopen("a.in","r",stdin);
  72. #else
  73. #endif
  74. memset(headE,-,sizeof(headE));
  75. memset(head,-,sizeof(head));
  76. N=read();M=read();S=,T=*(M+);
  77. for(int i=;i<=M;i++)
  78. {
  79. int x=read(),y=read(),z=read();
  80. add_edge(x,y,z);
  81. add_edge(y,x,z);
  82. }
  83. for(int i=;i<=N;i++)
  84. {
  85. int tempnum=;
  86. for(int j=headE[i];j!=-;j=E[j].nxt)
  87. temp[++tempnum]=j;
  88. sort(temp+,temp+tempnum+,comp);
  89. for(int j=;j<=tempnum;j++)
  90. {
  91. int x=temp[j],y=temp[j+];
  92. if(E[x].u==)
  93. AddEdge(S,x,E[x].w);
  94. if(E[x].v==N)
  95. AddEdge(x,T,E[x].w);
  96. AddEdge(x^,x,E[x].w);
  97. if(j!=tempnum)
  98. AddEdge(x,y,E[y].w-E[x].w),
  99. AddEdge(y,x,);
  100. }
  101. }
  102. Dijstra();
  103. return ;
  104. }

BZOJ 4289: PA2012 Tax(最短路)的更多相关文章

  1. BZOJ 4289: PA2012 Tax 差分建图 最短路

    https://www.lydsy.com/JudgeOnline/problem.php?id=4289 https://www.cnblogs.com/clrs97/p/5046933.html  ...

  2. ●BZOJ 4289 PA2012 Tax

    ●赘述题目 算了,题目没有重复的必要. 注意理解:对答案造成贡献的是每个点,就是了. 举个栗子: 对于如下数据: 2 1 1 2 1 答案是 2: ●题解 方法:建图(难点)+最短路. 先来几个链接: ...

  3. BZOJ.4289.PA2012 Tax(思路 Dijkstra)

    题目链接 \(Description\) 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价 ...

  4. bzoj 4289 PA2012 Tax——构图

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 可以把一个点上的边按权值排序,然后边权小的向第一个比它大的连差值的边,边权大的向第一个 ...

  5. bzoj 4289: PA2012 Tax

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

  6. 【刷题】BZOJ 4289 PA2012 Tax

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

  7. BZOJ 4289: PA2012 Tax Dijkstra + 查分

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

  8. [BZOJ4289][PA2012]TAX(最短路)

    首先考虑一种暴力做法,为每条边拆成两条有向边,各建一个点.若某两条边有公共点,则在边所对应的点之间连一条边,权值为两条边中的较大值.这样跑最短路是$O(m^2\log m)$的. 用类似网络流中补流的 ...

  9. [BZOJ4289] [PA2012] Tax 解题报告 (最短路+差分建图)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 4289: PA2012 Tax Time Limit: 10 Sec  Memo ...

随机推荐

  1. Java语言的优点

    1)Java为纯面向对象的语言. <Thinking in Java>提到Java语言是一种“Everything is object”的语言,它能够直接反应现实生活中的对象, 例如火车, ...

  2. js 数据类型判断

    判断type类型 isString (o) { //是否字符串 return Object.prototype.toString.call(o).slice(8, -1) === 'String' } ...

  3. 移动互联网iOS工程师必须知道的三点

    如果十年磨一剑,那么现在起作为一名iOS工程师,以下三点你必须要知道: 1.现在开始学swift正是时候,永远不要怕晚 因为…新时代的程序语言Swift有很多优势,长江后浪推前浪,Swift上手快,开 ...

  4. ZBrush创建人体模型-ZBrush中ZSphere的基本使用

    本教程我们将学习ZSphere(Z球)在ZBrush®中的基本使用情况,了解它在个人创作过程中发挥着怎样的作用.作为ZBrush中的独特功能之一,ZSphere能够让用户通过清晰的拓扑结构创建基础模型 ...

  5. day01 编程概述及计算机组成原理

    目录 编程概述 计算机硬件的五大组成部分 Central Processing Unit(cpu中央处理器) 存储器 输入,输出设备 打开QQ的流程 计算机五大组成部分补充 多核CPU ×64/x86 ...

  6. luoguP4512 【模板】多项式除法 NTT+多项式求逆+多项式除法

    Code: #include<bits/stdc++.h> #define maxn 300000 #define ll long long #define MOD 998244353 # ...

  7. UVALive-8077 Brick Walls 找规律

    题目链接:https://cn.vjudge.net/problem/UVALive-8077 题意 有一个用砖头磊起来的墙,现在又有一只蚂蚁,想沿着砖缝从起点跑到终点. 问最短路长度. 思路 找规律 ...

  8. BZOJ 1176/2683 Mokia (三维偏序CDQ+树状数组)

    题目大意: 洛谷传送门 三维偏序裸题.. 每次操作都看成一个三元组$<x,y,t>$,表示$x,y$坐标和操作时间$t $ 询问操作拆成$4$个容斥 接下来就是$CDQ$了,外层按t排序, ...

  9. BZOJ 1396 识别子串 (后缀自动机+线段树)

    题目大意: 给你一个字符串S,求关于每个位置x的识别串T的最短长度,T必须满足覆盖x,且T在S中仅出现一次 神题 以节点x为结尾的识别串,必须满足它在$parent$树的子树中只有一个$endpos$ ...

  10. VUE:渐进式JavaScript框架(小白自学)

    VUE:渐进式JavaScript框架 一.官网 英文 https://vuejs.org/ 中文 https://cn.vuejs.org/ 二:渐进式 即有一个核心库,在需要的时候再逐渐添加插件的 ...