BZOJ 1050 旅行
Description
给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。
Input
第一行包含两个正整数,N和M。 下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向公路,车辆必须以速度v在该公路上行驶。 最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。
Output
如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
Sample Input
4 2
1 2 1
3 4 2
1 4
【样例输入2】
3 3
1 2 10
1 2 5
2 3 8
1 3
【样例输入3】
3 2
1 2 2
2 3 4
1 3
Sample Output
IMPOSSIBLE
【样例输出2】
5/4
【样例输出3】
2
HINT
Source
自己YY了一个做法,感觉复杂度有点不太对,但跑起来还是飞快的。
枚举最大的边权,然后根据当前求出的最优答案找出最小边权,在这个范围内的边中做一遍最大生成树。先用并查集判断两点是否联通:不联通直接再见;否则再找出两点路径的最大值来更新答案。应该很好写,我都能想出来。
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
using namespace std; #define inf (1<<30)
#define maxn 510
#define maxm 5010 int n,m,up,down,side[maxn],toit[maxn*],next[maxn*];
int s,t,tot,cnt,father[maxn],bac[maxm],arr[maxn],len[maxn*];
double ans = (double)inf; bool in[maxn];
struct EDGE
{
int x,y,v;
friend inline bool operator <(const EDGE &a,const EDGE &b) { return a.v > b.v; }
}edge[maxm],temp[maxm]; inline void init() { for (int i = ;i <= n;++i) father[i] = i; } inline int find(int a) { if (father[a]!=a) father[a] = find(father[a]); return father[a]; } inline int gcd(int a,int b) { return b?gcd(b,a%b):a; } inline void add(int a,int b,int c)
{
next[++cnt] = side[a]; side[a] = cnt;
toit[cnt] = b; len[cnt] = c;
} inline void ins(int a,int b,int c) { add(a,b,c); add(b,a,c); } inline int bfs()
{
int team[maxn],*head,*tail;
head = tail = team; memset(in,false,n+);
*(++tail) = s; in[s] = true; arr[s] = inf;
while (head != tail)
{
int now = *(++head);
if (now == t) return arr[t];
for (int i = side[now];i;i = next[i])
if (!in[toit[i]]) *(++tail) = toit[i],arr[toit[i]] = min(arr[now],len[i]),in[toit[i]] = true;
}
} inline void work(int key)
{
int lim = key/ans,all = ,k = ;
for (int i = ;i <= m;++i) if (edge[i].v>lim&&edge[i].v <= key) temp[++all] = edge[i];
init(); memset(side,,*(n+)); cnt = ;
sort(temp+,temp+all+);
for (int i = ;i <= all;++i)
{
int r1 = find(temp[i].x),r2 = find(temp[i].y);
if (r1 != r2)
father[r1] = r2,ins(temp[i].x,temp[i].y,temp[i].v),++k;
if (k == n-) break;
}
if (find(s) != find(t)) return;
lim = bfs();
if ((1.0*key)/(1.0*lim) < ans) ans = (1.0*key)/(1.0*lim),up = key,down = lim;
} int main()
{
freopen("1050.in","r",stdin);
freopen("1050.out","w",stdout);
scanf("%d %d",&n,&m);
init();
for (int i = ;i <= m;++i)
{
int a,b,c; scanf("%d %d %d",&a,&b,&c);
edge[i] = (EDGE){a,b,c};
int r1 = find(a),r2 = find(b);
if (r1 != r2) father[r1] = r2;
bac[++tot] = c;
}
scanf("%d %d",&s,&t);
if (find(s) != find(t)) printf("IMPOSSIBLE\n"),exit();
sort(bac+,bac+tot+); tot = unique(bac+,bac+tot+)-bac-;
for (int i = tot;i;--i) work(bac[i]);
int d = gcd(up,down);
up /= d; down /= d;
if (down != ) printf("%d/%d",up,down);
else printf("%d",up);
fclose(stdin); fclose(stdout);
return ;
}
BZOJ 1050 旅行的更多相关文章
- BZOJ 1050 旅行comf(枚举最小边-并查集)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1050 题意:给出一个带权图.求一条s到t的路径使得这条路径上最大最小边的比值最小? 思路 ...
- BZOJ 1050 旅行comf 并查集+枚举下界
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1050 题目大意: 给你一个无向图,N(N<=500)个顶点, M(M<=5 ...
- BZOJ 1050 旅行comf
题目如下: 题目描述 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求一条路径,使得路径上最大边 ...
- [BZOJ]1050 旅行comf(HAOI2006)
图论一直是小C的弱项,相比其它题型,图论的花样通常会更多一点,套路也更难捉摸. Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权 ...
- BZOJ 1050 旅行(并查集)
很好的一道题.. 首先把边权排序.然后枚举最小的边,再依次添加不小于该边的边,直到s和t联通.用并查集维护即可. # include <cstdio> # include <cstr ...
- HYSBZ - 1050(旅行comf 并查集Java实现)
HYSBZ - 1050(旅行comf Java实现) 原题地址 解法:枚举每一条边,对于这条边,我们需要找到集合中和其值相差最小的最大边,这个集合是指与包括i边在内的ST联通集.对于这一要求,我们只 ...
- BZOJ 1050 [HAOI2006]旅行comf
1050: [HAOI2006]旅行comf Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1889 Solved: 976[Submit][Sta ...
- BZOJ 1050: [HAOI2006]旅行comf( 并查集 )
将edge按权值排序 , O( m² ) 枚举边 , 利用并查集维护连通信息. ------------------------------------------------------------ ...
- 【BZOJ 1050】1050: [HAOI2006]旅行comf (动态SPFA)
1050: [HAOI2006]旅行comf Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000). ...
随机推荐
- eclipse有时新建一个PHP文件或者是HTML文件没有快捷键太麻烦了,总要用鼠标点 怎么创建自己的快捷键呢?
问题:总是在eclipse上编写PHp程序和对应的HMTL模板文件,但是却没有可以直接新PHP文件和HTMl文件的快捷方式,苦恼. 在百度上搜了一下,我们是可以创建自己的组合快捷键的. 创建快捷键的方 ...
- Maven实现Web应用集成測试自己主动化 -- 部署自己主动化(WebTest Maven Plugin)
上篇:Maven实现Web应用集成測试自己主动化 -- 測试自己主动化(WebTest Maven Plugin) 之前介绍了怎样在maven中使用webtest插件实现web的集成測试,这里有个遗留 ...
- [RxJS] Aggregating Streams With Reduce And Scan using RxJS
What is the RxJS equivalent of Array reduce? What if I want to emit my reduced or aggregated value a ...
- wikioi 2573 大顶堆与小顶堆并用
题目描写叙述 Description 我们使用黑匣子的一个简单模型.它能存放一个整数序列和一个特别的变量i.在初始时刻.黑匣子为空且i等于0. 这个黑匣子能运行一系列的命令.有两类命令: ADD(x) ...
- Qt 学习之路 :动态视图
Repeater适用于少量的静态数据集.但是在实际应用中,数据模型往往是非常复杂的,并且数量巨大.这种情况下,Repeater并不十分适合.于是,QtQuick 提供了两个专门的视图元素:ListVi ...
- Scope Chain(作用域链)
本章,我们讨论一下ECMAScript中的作用域链 , 开门见山. 什么是作用域链 i.ECMAScript是允许创建内部函数的,甚至能从父函数中返回这些函数.作用域链正是内部上下文中所有变量对象(及 ...
- 史上最全WebView使用,附送Html5Activity一份
本文来自:http://www.jianshu.com/users/320f9e8f7fc9/latest_articles感谢您的关注. WebView在现在的项目中使用的频率应该还是非常高的.我个 ...
- Bat命令知识[转]
基础部分: 一.基础语法: 1.批处理文件是一个".bat"结尾的文本文件,这个文件的每一行都是一条DOS命令.可以使用任何文本文件编辑工具创建和修改. 2.批处理是一种简单的程序 ...
- android如何获取手机型号和版本号
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView ...
- android SDK 代理配置(东北大学)
启动 Android SDK Manager ,打开主界面,依次选择「Tools」.「Options...」,弹出『Android SDK Manager - Settings』窗口: 在『Andro ...