P2502 [HAOI2006]旅行 最小生成树

思路:枚举边集,最小生成树

提交:1次

题解:(如思路)

#include<cstdio>
#include<iostream>
#include<algorithm>
#define R register int
using namespace std;
#define ull unsigned long long
#define ll long long
#define pause (for(R i=1;i<=10000000000;++i))
#define In freopen("NOIPAK++.in","r",stdin)
#define Out freopen("out.out","w",stdout)
namespace Fread {
static char B[1<<15],*S=B,*D=B;
#ifndef JACK
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
#endif
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==‘-‘?-1:fix;
    if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
} inline bool isempty(const char& ch) {return (ch<=36||ch>=127);}
inline void gs(char* s) {
    register char ch; while(isempty(ch=getchar()));
    do *s++=ch; while(!isempty(ch=getchar()));
}
} using Fread::g; using Fread::gs;

namespace Luitaryi {
const int N=510,M=5010;
int n,m,s,t,up,dn;
double anss=1E+9;
int fa[N];
struct edge { int u,v,w;
    inline bool operator < (const edge& that) const{return w<that.w;}
}e[M];
inline int getf(int x) {return x==fa[x]?x:fa[x]=getf(fa[x]);}
inline void main() {
    n=g(),m=g();
    for(R i=1;i<=m;++i) e[i].u=g(),e[i].v=g(),e[i].w=g();
    sort(e+1,e+m+1); s=g(),t=g();
    for(R i=1;i<=m;++i) { R ans=0;//枚举下界,最小的边
        for(R j=1;j<=n;++j) fa[j]=j;
        for(R j=i;j<=m;++j) {//往上枚举,直到两点连通
            R uf=getf(e[j].u),vf=getf(e[j].v);
            fa[uf]=vf;
            if(getf(s)==getf(t)) {ans=j; break;}
        } if(i==1&&ans==0) return (void)printf("IMPOSSIBLE\n");
        if(ans==0) break; register double tmp=1.0*e[ans].w/e[i].w;
        if(tmp<anss) anss=tmp,up=e[ans].w,dn=e[i].w;
    } R tmp=__gcd(up,dn); if(tmp==dn) printf("%d\n",up/dn);
    else printf("%d/%d\n",up/tmp,dn/tmp);
}
}
signed main() {
    Luitaryi::main();
    return 0;
} 


2019.07.20

原文地址:https://www.cnblogs.com/Jackpei/p/11217346.html

时间: 2024-07-31 01:32:22

P2502 [HAOI2006]旅行 最小生成树的相关文章

P2502 [HAOI2006]旅行 - 最小生成树【最小比值生成树(雾】

P2502 [HAOI2006]旅行 Sol: 暴力 枚举所有从S到T的路径,然后用maxw/minw更新答案. 时间复杂度:\(O(玄学)\) 正解 观察到边数\(m\leq5000\) 考虑由直接求maxw和minw -> 枚举minw求maxw 由于从S到T的路径上的最大值最小的边一定在最小生成树上(最小生成树的瓶颈路性质),所以我们可以将边从小到大排序,每次枚举边\(e_i\),并将剩下的\(e_i,e_{i+1}\dots e_m\)建最小生成树,当边\(e_k\)使S和T第一次连通时

luogu题解P2502[HAOI2006]旅行--最小生成树变式

题目链接 https://www.luogu.org/problemnew/show/P2502 分析 一个很\(naive\)的做法是从\(s\)到\(t\)双向BFS这当然会TLE 这时我就有个想法就是二分套二分边下标来求得一个比值,同时排序后从小到大枚举每一条边作为最小值,同时再枚举每一条边,如果边权之比小于比值就连起来用并查集维护连通性,可是这个时间复杂度\(O(m^2 log^2m \ \alpha(n))\)过不去QAQ 然后想为什么不直接枚举每条边作为最小值,同时搞一颗以这条边为最

luogu P2502 [HAOI2006]旅行

传送门 边数只有5000,可以考虑\(O(m^2)\)算法,即把所有边按边权升序排序,然后依次枚举每条边\(i\),从这条边开始依次加边,加到起点和终点在一个连通块为止.这个过程可以用并查集维护.那么以\(i\)这条边为最小边的合法路径,最大值最小的边就是最后加进去的边,这时用这两个边权更新答案即可 可以加一些形如当前比值比答案更差就退出的剪枝 #include<bits/stdc++.h> #define LL long long #define il inline #define re r

bzoj 1050: [HAOI2006]旅行comf(最小生成树+并查集)

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2405  Solved: 1282 [Submit][Status][Discuss] Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T ,求一条路径,使得路径上最大边和最小边的比值最小.如果S和T之间没有路径,输出"IMPOSS

1050: [HAOI2006]旅行comf

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1495  Solved: 737[Submit][Status] Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小.如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个比值,如果需

[HAOI2006]旅行comf

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3450  Solved: 1919 [Submit][Status][Discuss] Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求 一条路径,使得路径上最大边和最小边的比值最小.如果S和T之间没有路径,输出"IMPOSS

BZOJ 1050: [HAOI2006]旅行comf(枚举+并查集)

[HAOI2006]旅行comf Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小.如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个比值,如果需要,表示成一个既约分数. 备注: 两个顶点之间可能有多条路径. Input 第一行包含两个正整数,N和M.下来的M行每行包含三个正整数:x,y和v.表示景点x到景点y之间有一条

[HAOI2006]旅行 题解(kruskal)

[HAOI2006]旅行 Description Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光.Z小镇附近共有N个景点(编号为1,2,3,-,N),这些景点被M条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路.也许是为了保护该地的旅游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi.速度变化太快使得游客们很不舒服,因此从一个景点前往另一个景点的时候,大家都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最

玲珑杯 Round15 E咸鱼旅行 最小生成树+BFS

题目链接:http://www.ifrog.cc/acm/problem/1126 maxn = 500005. 不然RE..... 思路:跑一遍最小生成树然后bfs找一下即可. wa了N次,发现自己并没有真正理解并查集的合并:x = find(u), y = find(v), p[x] = y,等价于先find(u) find(v)之后(需要路径压缩)p[p[u]] = p[v] 或者p[p[v]] = p[u] 不过纯粹自己写kruskal + bfs + 并查 AC的感觉还是很爽的. 代码