uva 10816 Travel in Desert(简单的好题~两种方法)
题意:
给出 一个图
点与点之间的路径上有两个权值 路径长度和温度
要求在所走路径中的温度的最大值最小的前提下 走最短路径
解题思路1:
首先用 最小生成树 的方法走出 最小瓶颈路 。把在这期间用到的全部温度小于 路径上最大温度 的边存下来,作为接下来求最短路径的图。
在新生成的图中求最短路径就可以;
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std; const int maxm = 10005;
const int maxn = 105; struct Edge{
int u,v;
double dist,tm;
void read(){
scanf("%d%d%lf%lf",&u,&v,&tm,&dist);
u--;v--;
}
bool operator<(const Edge et)const{
if(tm != et.tm) return tm < et.tm;
else return dist < et.dist;
}
}e[maxm];
int n,m,s,t;
int parent[maxn];
vector<Edge> g[maxn]; void init(){
scanf("%d%d",&s,&t);
s--;t--;
for(int i = 0; i < m; i++){
e[i].read();
}
for(int i = 0; i < n; i++){
g[i].clear();
}
}
int find(int x){
if(parent[x] == x) return x;
else return parent[x] = find(parent[x]);
} const int INF = 0x3f3f3f3f;
const int MAXNODE = 105; struct Edge2 {
int u, v;
double dist;
Edge2() {}
Edge2(int u, int v, double dist) {
this->u = u;
this->v = v;
this->dist = dist;
}
};
struct HeapNode {
double d;
int u;
HeapNode() {}
HeapNode(double d, int u) {
this->d = d;
this->u = u;
}
bool operator < (const HeapNode& c) const {
return d > c.d;
}
};
struct Dijkstra {
int n, m;
vector<Edge2> edges;
vector<int> g[MAXNODE];
bool done[MAXNODE];
double d[MAXNODE];
int p[MAXNODE]; void init(int tot) {
n = tot;
for (int i = 0; i < n; i++)
g[i].clear();
edges.clear();
} void add_Edge(int u, int v, double dist) {
edges.push_back(Edge2(u, v, dist));
m = edges.size();
g[u].push_back(m - 1);
} void print(int s, int e) {//shun xu
if (s == e) {
printf("%d", e + 1);
return;
}
print(s, edges[p[e]].u);
printf(" %d", e + 1);
} void print2(int s, int e) {//ni xu
if (s == e) {
printf("%d", e + 1);
return;
}
printf("%d ", e + 1);
print2(s, edges[p[e]].u);
} void dijkstra(int s) {
priority_queue<HeapNode> Q;
for (int i = 0; i < n; i++) d[i] = INF*1.0;
d[s] = 0.0;
memset(done, false, sizeof(done));
Q.push(HeapNode(0, s));
while (!Q.empty()) {
HeapNode x = Q.top(); Q.pop();
int u = x.u;
if (done[u]) continue;
done[u] = true;
for (int i = 0; i < g[u].size(); i++) {
Edge2& e = edges[g[u][i]];
if (d[e.v] > d[u] + e.dist) {
d[e.v] = d[u] + e.dist;
p[e.v] = g[u][i];
Q.push(HeapNode(d[e.v], e.v));
}
}
}
}
} graph; void solve(){
// printf("...\n");
double ans = 0;
sort(e,e+m); // for(int i = 0; i < m; i++){
// printf("%.1lf %.1lf %d %d\n",e[i].dist,e[i].tm,e[i].u,e[i].v);
// }
for(int i = 0; i < n; i++) parent[i] = i; double max_tm = 500.0;
graph.init(n);
for(int i = 0; i < m; i++){
if(e[i].tm > max_tm) break;
graph.add_Edge(e[i].u,e[i].v,e[i].dist);
graph.add_Edge(e[i].v,e[i].u,e[i].dist); int pu = find(e[i].u);
int pv = find(e[i].v);
if(pu == pv) continue;
parent[pu] = pv; if(find(s) == find(t)){
max_tm = e[i].tm;
}
} graph.dijkstra(s);
graph.print(s,t);
printf("\n");
printf("%.1lf %.1lf\n",graph.d[t],max_tm); }
int main(){
while(scanf("%d%d",&n,&m) != EOF){
init();
solve();
}
return 0;
}
解题思路二:
把原图存下来,然后二分温度,再把全部小于温度mid的边拿出来构成一个新图,然后继续dijkstra求最短路,有成功和不成功两种结果,找到能成功的最小温度就可以
code
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std; const int MAXNODE = 105;
const int MAXEDGE = 20005; typedef double Type;
const Type INF = 0x3f3f3f3f; struct Edge {
int u, v;
Type dist, d;
Edge() {}
Edge(int u, int v, Type dist, Type d = 0) {
this->u = u;
this->v = v;
this->dist = dist;
this->d = d;
}
void read() {
scanf("%d%d%lf%lf", &u, &v, &d, &dist);
u--; v--;
}
}; struct HeapNode {
Type d;
int u;
HeapNode() {}
HeapNode(Type d, int u) {
this->d = d;
this->u = u;
}
bool operator < (const HeapNode& c) const {
return d > c.d;
}
}; int n, m, s, t; struct Dijkstra {
int n, m;
Edge edges[MAXEDGE];
int first[MAXNODE];
int next[MAXEDGE];
bool done[MAXNODE];
Type d[MAXNODE];
int p[MAXNODE]; void init(int n) {
this->n = n;
memset(first, -1, sizeof(first));
m = 0;
} void add_Edge(int u, int v, Type dist) {
edges[m] = Edge(u, v, dist);
next[m] = first[u];
first[u] = m++;
} void add_Edge(Edge e) {
edges[m] = e;
next[m] = first[e.u];
first[e.u] = m++;
}
void print(int e) {//shun xu
if (p[e] == -1) {
printf("%d", e + 1);
return;
}
print(edges[p[e]].u);
printf(" %d", e + 1);
} void print2(int e) {//ni xu
if (p[e] == -1) {
printf("%d\n", e + 1);
return;
}
printf("%d ", e + 1);
print2(edges[p[e]].u);
} bool dijkstra(int s, int t) {
priority_queue<HeapNode> Q;
for (int i = 0; i < n; i++) d[i] = INF;
d[s] = 0;
p[s] = -1;
memset(done, false, sizeof(done));
Q.push(HeapNode(0, s));
while (!Q.empty()) {
HeapNode x = Q.top(); Q.pop();
int u = x.u;
if (u == t)
return true;
if (done[u]) continue;
done[u] = true;
for (int i = first[u]; i != -1; i = next[i]) {
Edge& e = edges[i];
if (d[e.v] > d[u] + e.dist) {
d[e.v] = d[u] + e.dist;
p[e.v] = i;
Q.push(HeapNode(d[e.v], e.v));
}
}
}
return false;
}
} gao; Edge e[MAXEDGE]; bool judge(double mid) {
gao.init(n);
for (int i = 0; i < m; i++) {
if (e[i].d > mid) continue;
gao.add_Edge(e[i]);
gao.add_Edge(Edge(e[i].v, e[i].u, e[i].dist, e[i].d));
}
if (gao.dijkstra(s, t)) return true;
return false;
} int main() {
while (~scanf("%d%d", &n, &m)) {
scanf("%d%d", &s, &t);
s--; t--;
for (int i = 0; i < m; i++)
e[i].read();
double l = 0, r = 50, mid;
while (r - l > 1e-8) {
mid = (l + r) / 2;
if (judge(mid)) r = mid;
else l = mid;
}
if (judge(r)) {
gao.print(t); printf("\n");
printf("%.1lf %.1lf\n", gao.d[t], mid);
}
}
return 0;
}
二分在非常多情况下都是非常好用的一种方法~
uva 10816 Travel in Desert(简单的好题~两种方法)的更多相关文章
- 在vc6.0下编的对话框界面如果没做过其他处理,往往显的很生硬,怎么样才能使他有Windows XP的风格呢,其实也很简单,我们来看看下面两种方法。
在vc6.0下编的对话框界面如果没做过其他处理,往往显的很生硬,怎么样才能使他有Windows XP的风格呢,其实也很简单,我们来看看下面两种方法. 方法一: 1.首先确认你在Windows ...
- Java中的策略模式,完成一个简单地购物车,两种付款策略实例教程
策略模式是一种行为模式.用于某一个具体的项目有多个可供选择的算法策略,客户端在其运行时根据不同需求决定使用某一具体算法策略. 策略模式也被称作政策模式.实现过程为,首先定义不同的算法策略,然后客户端把 ...
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
软件152 尹以操 首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml ...
- C#通过模板导出Word的两种方法(超简单)
方法一:使用Office的组件 使用该方法必须要安装Office 1.制作Word模板 在需要填充内容的地方增加标识符号,方便之后替换使用,例如 [项目名称],其中[]符号和中间的文字可根据个人情况进 ...
- 用idea简单创建web项目——两种方式
最近同学让我教她们用idea创建web项目,于是我用两种方式创建web项目,并整理截图给她们看,一种是用maven创建,一种是不用maven创建,适合菜鸟哈哈~ 方法一:不用maven 1.解压tom ...
- Easy-UI中datebox的默认显示当前日期的最简单的两种方法
在中有一个Today按钮就是实现显示当前日期,所以我们在src/jquery.datebox.js文件中可以找到currentText:'Today'.所以我们可以使用'currentText'和'T ...
- 【leetcode 简单】第一题 两数之和
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...
- C语言播放声音最简单的两种方法
1. 假设仅须要播放波形文件wav格式的声音,非常easy.仅仅需一句话: PlaySound(TEXT("Data\\1.wav"), NULL, SND_FILENAME | ...
- Visual Studio写的项目在 IIS 服务器上运行的两种简单方法
首先需要PC上开启了IIS服务,相关方法网上很多,也很简单 第一种:直接在项目中操作 1.创建一个项目,然后右击选中项目,右击,单击属性,打开项目属性标签页面 如图,选择Web标签,在服务器栏目中选中 ...
随机推荐
- mysql报错问题解决MySQL server PID file could not be found!
MySQL server PID file could not be found! 无法启动mysql服务 # service mysqld start MySQL server PID file c ...
- Ex 6_5棋子放置问题_第八次作业
题目貌似有问题 (b) 子问题定义: 设maxValue[i][j]为棋盘的前i行中最后一行为i时第i行按照第j种放置方式放置时得到的最大覆盖值,comp[i][j]为第i种放置方式与第j种放置方式是 ...
- 破解idea
2019最新注册码 地址: http://idea.lanyus.com/ https://blog.csdn.net/best_luxi/article/details/81479820
- poj3579 二分套二分
和poj3685类似,都是二分答案然后在判断时再二分 这题的内层二分可以用stl代替 /* 二分套二分,思路:升序排序数据,先二分答案x进行判断,判断时枚举每个元素,二分找到和其之差小于等于x的所有值 ...
- 主机可以ping通虚拟机,但是虚拟机ping不通主机的方法(转)
https://blog.csdn.net/hskw444273663/article/details/81301470
- FXML Stuffs (include and define)
FXML Stuffs (include and define)Hello folks,Today I would like to blog about the FXML define and inc ...
- [ZJOI2012]旅游
题目: 这题意...还以为他说的线段是路径 写了好久的dp..写不出来 看了网上的题解..才知道就是两点连线 然后就是一般的平面图转对偶图的思想 然后算一下边数发现是颗树,求一下直径就好了 代码: # ...
- FFT 【JSOI2012】bzoj4332 分零食 (未解决)
很不错的一道倍增优化dp?? 第一次做这类题挺难想的 题目大意: 有n个小朋友,m块糖. 给小朋友分糖,如果一个小朋友分不到糖,那他后面的小朋友也分不到糖. 每个小朋友有一个喜悦值,有三个参数,O,S ...
- BZOJ3377 [Usaco2004 Open]The Cow Lineup 奶牛序列 其他
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3377 题意概括 给出一个序列,序列中的数字为1~k中的. 让你求最短的非子序列长度. 题解 我们把 ...
- 【Java】 剑指offer(19) 正则表达式匹配
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请实现一个函数用来匹配包含'.'和'*'的正则表达式.模式中的字符 ...