POJ - 3662 Telephone Lines (Dijkstra+二分)
2024-08-27 11:13:59
题意:一张带权无向图中,有K条边可以免费修建。现在要修建一条从点1到点N的路,费用是除掉免费的K条边外,权值最大的那条边的值,求最小花费。
分析:假设存在一个临界值X,小于X的边全部免费,那么此时由大于等于X的边组成的图,从点1到点N走过的边数小于等于K,那么这个X就是所求的答案。所以可以通过二分答案的方法求解该问题,每一次根据mid值跑迪杰斯特拉,d[i]记录路径长度(走过边的数目)。需要注意的是,要特判一下点1到点N本身不连通的情况以及花费为0的情况。二分的时候,当d[N]>K时修改答案为mid,因为此时能确定最后的结果一定大于等于mid。
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
typedef int LL;
const int maxn =1e3+;
const int maxm =5e4+;
const LL INF =0x3f3f3f3f;
struct Edge{
int from,to,next;
LL val;
bool operator <(const Edge &e) const {return val<e.val;}
}; struct HeapNode{
LL d; //费用或路径
int u;
bool operator < (const HeapNode & rhs) const{return d > rhs.d;}
};
struct Dijstra{
int n,m,tot;
Edge edges[maxm];
bool used[maxn];
LL d[maxn];
int head[maxn]; void init(int n){
this->n = n;
this->tot=;
memset(head,-,sizeof(head));
} void Addedge(int u,int v ,LL dist){
edges[tot].to = v;
edges[tot].val = dist;
edges[tot].next = head[u];
head[u] = tot++;
} int dijkstra(int s,int limit){
memset(used,,sizeof(used));
priority_queue<HeapNode> Q;
for(int i=;i<=n;++i) d[i]=INF; //d[i]记录的是到i点走过的权值超过limit的边数
d[s]=;
Q.push((HeapNode){,s});
while(!Q.empty()){
HeapNode x =Q.top();Q.pop();
int u =x.u;
if(d[u]<x.d) continue; //没有更新的必要,不加判断也对,但是慢一点点
for(int i=head[u];~i;i=edges[i].next){
int nd = d[u]+(edges[i].val>=limit?:);
int v = edges[i].to;
if (d[v] > nd){
d[v] = nd;
Q.push({d[v], v});
}
}
}
return d[n];
}
}G; #define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int N,M,K,u,v,k;
LL tmp;
while(scanf("%d%d%d",&N,&M,&K)==){
G.init(N);
int maxL = -;
for(int i=;i<M;++i){
scanf("%d%d%d",&u,&v,&tmp);
G.Addedge(u,v,tmp);
G.Addedge(v,u,tmp);
if(maxL<tmp) maxL = tmp;
}
int res = G.dijkstra(,);
if(res==INF){
printf("-1\n");
continue;
}
else if(res<=K){ //先特判一下
printf("0\n");
continue;
}
int L =,R=maxL,mid,ans;
while(L<R){
mid =(L+R)>>;
if(G.dijkstra(,mid)>K){
ans = mid; //此时能确定的是:肯定要花费mid的代价
L = mid+;
}
else R =mid-;
}
printf("%d\n",ans);
}
return ;
}
最新文章
- spring-cloud-event-sourcing-example-master 运行效果及说明
- Unity3d中Update()方法的替身
- Socket客户端/服务端简单实例
- IOS 取消表格单元格 TableViewCell 去掉高亮状态 点击Cell取消选择状态
- CentOS 最小化安装后安装桌面
- zoj3229
- 解开神秘面纱之“AngualrJS 中指令相关的嵌入作用域和模板作用域”
- 关于修改了db2 instance下面文件夹权限导致的不可连接
- 201521123121 《Java程序设计》第3周学习总结
- 【懒人有道】在asp.net core中实现程序集注入
- The authenticity of host &#39;github.com (192.30.253.113)&#39; can&#39;t be established.
- 设置元素text-overflow: ellipsis后引起的文本对齐问题
- vue-lazyload 图片依赖加载
- Android Lifecycle使用
- ffmpeg切割视频
- java poi excel操作 下拉菜单 及数据有效性
- svn的安装方法
- UVA-1663 Purifying Machine (最大匹配数)
- 使用fetch出现unexpected end of input 解决方法
- jersey之get,put,post,delete简单使用
热门文章
- Android开发 获取当前activity的屏幕截图(转载)
- 用Eclipse的tomcat插件启动tomcat时报错:
- 【BZOJ】1596: [Usaco2008 Jan]电话网络(树形dp+特殊的技巧)
- UE对话框
- 把xml格式的字符串写入到一个xml文件中
- poj 1322 Chocolate (概率dp)
- 面试题思考:IOC的优缺点
- iOS-更新CocoaPods出现错误 提示重复文件
- 《从零开始学Swift》学习笔记(Day 59)——代码排版
- 选项卡jQuery(ele).each()