题意:一张带权无向图中,有K条边可以免费修建。现在要修建一条从点1到点N的路,费用是除掉免费的K条边外,权值最大的那条边的值,求最小花费。

分析:假设存在一个临界值X,小于X的边全部免费,那么此时由大于等于X的边组成的图,从点1到点N走过的边数小于等于K,那么这个X就是所求的答案。所以可以通过二分答案的方法求解该问题,每一次根据mid值跑迪杰斯特拉,d[i]记录路径长度(走过边的数目)。需要注意的是,要特判一下点1到点N本身不连通的情况以及花费为0的情况。二分的时候,当d[N]>K时修改答案为mid,因为此时能确定最后的结果一定大于等于mid。

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<cstring>
  4. #include<queue>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<vector>
  8. using namespace std;
  9. typedef int LL;
  10. const int maxn =1e3+;
  11. const int maxm =5e4+;
  12. const LL INF =0x3f3f3f3f;
  13. struct Edge{
  14. int from,to,next;
  15. LL val;
  16. bool operator <(const Edge &e) const {return val<e.val;}
  17. };
  18.  
  19. struct HeapNode{
  20. LL d; //费用或路径
  21. int u;
  22. bool operator < (const HeapNode & rhs) const{return d > rhs.d;}
  23. };
  24. struct Dijstra{
  25. int n,m,tot;
  26. Edge edges[maxm];
  27. bool used[maxn];
  28. LL d[maxn];
  29. int head[maxn];
  30.  
  31. void init(int n){
  32. this->n = n;
  33. this->tot=;
  34. memset(head,-,sizeof(head));
  35. }
  36.  
  37. void Addedge(int u,int v ,LL dist){
  38. edges[tot].to = v;
  39. edges[tot].val = dist;
  40. edges[tot].next = head[u];
  41. head[u] = tot++;
  42. }
  43.  
  44. int dijkstra(int s,int limit){
  45. memset(used,,sizeof(used));
  46. priority_queue<HeapNode> Q;
  47. for(int i=;i<=n;++i) d[i]=INF; //d[i]记录的是到i点走过的权值超过limit的边数
  48. d[s]=;
  49. Q.push((HeapNode){,s});
  50. while(!Q.empty()){
  51. HeapNode x =Q.top();Q.pop();
  52. int u =x.u;
  53. if(d[u]<x.d) continue; //没有更新的必要,不加判断也对,但是慢一点点
  54. for(int i=head[u];~i;i=edges[i].next){
  55. int nd = d[u]+(edges[i].val>=limit?:);
  56. int v = edges[i].to;
  57. if (d[v] > nd){
  58. d[v] = nd;
  59. Q.push({d[v], v});
  60. }
  61. }
  62. }
  63. return d[n];
  64. }
  65. }G;
  66.  
  67. #define LOCAL
  68. int main()
  69. {
  70. #ifdef LOCAL
  71. freopen("in.txt","r",stdin);
  72. freopen("out.txt","w",stdout);
  73. #endif
  74. int N,M,K,u,v,k;
  75. LL tmp;
  76. while(scanf("%d%d%d",&N,&M,&K)==){
  77. G.init(N);
  78. int maxL = -;
  79. for(int i=;i<M;++i){
  80. scanf("%d%d%d",&u,&v,&tmp);
  81. G.Addedge(u,v,tmp);
  82. G.Addedge(v,u,tmp);
  83. if(maxL<tmp) maxL = tmp;
  84. }
  85. int res = G.dijkstra(,);
  86. if(res==INF){
  87. printf("-1\n");
  88. continue;
  89. }
  90. else if(res<=K){ //先特判一下
  91. printf("0\n");
  92. continue;
  93. }
  94. int L =,R=maxL,mid,ans;
  95. while(L<R){
  96. mid =(L+R)>>;
  97. if(G.dijkstra(,mid)>K){
  98. ans = mid; //此时能确定的是:肯定要花费mid的代价
  99. L = mid+;
  100. }
  101. else R =mid-;
  102. }
  103. printf("%d\n",ans);
  104. }
  105. return ;
  106. }

POJ - 3662 Telephone Lines (Dijkstra+二分)的更多相关文章

  1. poj 3662 Telephone Lines dijkstra+二分搜索

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5696   Accepted: 2071 D ...

  2. POJ 3662 Telephone Lines(二分答案+SPFA)

    [题目链接] http://poj.org/problem?id=3662 [题目大意] 给出点,给出两点之间连线的长度,有k次免费连线, 要求从起点连到终点,所用的费用为免费连线外的最长的长度. 求 ...

  3. POJ 3662 Telephone Lines (二分 + 最短路)

    Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncoop ...

  4. POJ 3662 Telephone Lines【二分答案+最短路】||【双端队列BFS】

    <题目链接> 题目大意: 在一个节点标号为1~n的无向图中,求出一条1~n的路径,使得路径上的第K+1条边的边权最小. 解题分析:直接考虑情况比较多,所以我们采用二分答案,先二分枚举第K+ ...

  5. (poj 3662) Telephone Lines 最短路+二分

    题目链接:http://poj.org/problem?id=3662 Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total ...

  6. POJ 3662 Telephone Lines【Dijkstra最短路+二分求解】

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7214   Accepted: 2638 D ...

  7. poj 3662 Telephone Lines(最短路+二分)

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6973   Accepted: 2554 D ...

  8. poj 3662 Telephone Lines

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7115   Accepted: 2603 D ...

  9. poj 3662 Telephone Lines spfa算法灵活运用

    意甲冠军: 到n节点无向图,它要求从一个线1至n路径.你可以让他们在k无条,的最大值.如今要求花费的最小值. 思路: 这道题能够首先想到二分枚举路径上的最大值,我认为用spfa更简洁一些.spfa的本 ...

随机推荐

  1. QT creator 编辑多个UI 文件 出现 无法解析的外部符号的错误

    创建一般的Qt Gui 程序一般会默认一个UI 文件 ,但是随着应用程序窗口的增多,同时编辑多个UI 界面是必须的. 假设我们已经创建好了一个QTUI的工程,里面已经默认了一个UI文件,但是想在添几个 ...

  2. 第一百五十二节,封装库--JavaScript,表单验证--年月日注入

    封装库--JavaScript,表单验证--年月日注入 效果图 html <div id="reg"> <h2 class="tuo"> ...

  3. android手机有多个摄像头,打开其中一个

    方法: private Camera openFrontFacingCameraGingerbread() { int cameraCount = 0; Camera cam = null; Came ...

  4. 自定义ScrollView 支持添加头部

    自定义ScrollView 支持添加头部并且对头部ImageView支持放大缩小,上滑头部缩小,下滑头部显示放大 使用方式: scrollView = (MyScrollView) findViewB ...

  5. Android 中替代 sharedpreferences 工具类的实现

    Android 中替代 sharedpreferences 工具类的实现 背景 想必大家一定用过 sharedpreferences 吧!就我个人而言,特别讨厌每次 put 完数据还要 commit. ...

  6. 1.0_搭建PHP服务器环境的步骤

    a,下载安装一款静态web服务器,ex:HTTPD,IIS; b,下载安装PHP引擎: c,在静态服务器配置一下,声明PHP引擎的存在. 注意,以上三步可以用xampp套件来完成. 启动Apache, ...

  7. jpa单向一对一关系外键映射

    项目结构: Wife package auth.model; import javax.persistence.Column; import javax.persistence.Entity; imp ...

  8. 170220、maven国内镜像 阿里云

    maven确实是一个好东西,但是在国内下载官方仓库的jar却是个大问题,速度不敢恭维,现在oschina的国内maven镜像服务已关闭,无奈之下只能另寻门路. 今天突然发现了阿里云maven国内镜像, ...

  9. java上传图片,把图片存到本地

    思路:js通过FileReader获取图片的Base64,Java解码用IO存到本地. HTML 代码 <input type="file" ng-model="f ...

  10. 【Linux】命令学习笔记和总结

    莫名的想学习一下Linux了,因为对这方面的知识储备为0.对于命令行界面始终是零接触零了解,对一个程序员来说这几乎是致命的,所以简单了解一下. 一.教程参考 参考菜鸟教程即可: Linux 教程 | ...