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

Posted loi-brilliant

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2502 [HAOI2006]旅行 - 最小生成树最小比值生成树(雾相关的知识,希望对你有一定的参考价值。

P2502 [HAOI2006]旅行

Sol:

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

    AC Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int read(){
    int x=0,f=1;char ch=‘ ‘;
    while(ch>‘9‘||ch<‘0‘) {if(ch==‘-‘) f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘) {x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
    return x*f;
}
const int N = 500 + 100,M = 5000 + 100;
int n,m,s,t;
struct node{
    int u,v,w;
    bool operator < (const node& a)const{
        return w<a.w;
    }
}e[M];
int gcd(int a,int b){
    return !b?a:gcd(b,a%b);
}
int fa[N];
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
double tmpmax;
int ansmax,ansmin;
bool ok;
void kruskal(int l){
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=l;i<=m;i++){
        int u=e[i].u,v=e[i].v,w=e[i].w;
        int p=find(u),q=find(v);
        if(p!=q){
            fa[p]=q;
        }
        if(find(s)==find(t)){
            tmpmax=w;
            ok=0;
            break;
        }
    }
    return ;
}
int main(){
//  freopen("data.in","r",stdin);
//  freopen("sol.out","w",stdout);
    n=read();m=read();
    for(int i=1;i<=n;i++) fa[i]=i;
    int tot=0;
    for(int i=1;i<=m;i++){
        int u,v,w;u=read();v=read();w=read();
        e[i]=(node){u,v,w};
        fa[find(u)]=find(v);
    }
    sort(e+1,e+m+1);
    s=read();t=read();
    if(find(s)!=find(t)){
        printf("IMPOSSIBLE");return 0;
    }
    double ans=10000000.0;
    for(int i=1;i<=m;i++){
        ok=1;
        kruskal(i);
        if(ok) continue;//S与T不连通
        double res=tmpmax/e[i].w;
        if(res<ans){
            ansmin=e[i].w;
            ansmax=floor(tmpmax);
            ans=min(ans,res);
        }
    }
    if(ansmax%ansmin==0){
        printf("%d",ansmax/ansmin);
    }
    else{
        int GCD=gcd(ansmin,ansmax);
        ansmin/=GCD,ansmax/=GCD;
        printf("%d/%d",ansmax,ansmin);
    }
    return 0;
}





以上是关于P2502 [HAOI2006]旅行 - 最小生成树最小比值生成树(雾的主要内容,如果未能解决你的问题,请参考以下文章

luogu P2502 [HAOI2006]旅行

P2502:[HAOI2006]旅行

[HAOI2006] 旅行

P2502 [HAOI2006]鏃呰 鏈€灏忕敓鎴愭爲

BZOJ [HAOI2006]旅行comf

1050: [HAOI2006]旅行comf