• bzoj 1050 [HAOI2006]旅行comf (并查集)


    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1050

    思路:

    先将每条边的权值排个序优先小的,然后从小到大枚举每一条边,将其存到并查集里,如果得到的比值比之前的小,那么判断下s与t能否连通,如果连通就替换就好了

    实现代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int M = 1e6+10;
    int f[M],vis[M],a[M];
    int n,m;
    int Find(int x){
        if(x==f[x])return x;
        return f[x]=Find(f[x]);
    }
    
    void mix(int x,int y){
        int fx = Find(x);
        int fy = Find(y);
        if(fx != fy) f[fx] = fy;
    }
    
    bool cmp(int a,int b){
        return a > b;
    }
    
    struct node{
        int x,y,v;
        bool operator < (const node &cmp) const{
             return v < cmp.v;
        }
    }e[M];
    
    int main()
    {
        int s,t;
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= m;i ++)
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v);
        sort(e+1,e+1+m);
        scanf("%d%d",&s,&t);
        int minn = 1,maxx = 30000;
        for(int i = 1;i <= m;i ++){
            for(int j = 1;j <= n;j ++)  f[j] = j;
            for(int j = i;j <= m;j ++){
                mix(e[j].x,e[j].y);
                if(e[j].v*minn > e[i].v*maxx) break;
                if(Find(s) == Find(t)){
                    int k = __gcd(e[j].v,e[i].v);
                    minn = e[i].v/k; maxx = e[j].v/k;
                   // cout<<k<<" "<<minn<<" "<<maxx<<endl;
                    break;
                }
            }
        }
        if(maxx == 30000&&minn == 1) printf("IMPOSSIBLE
    ");
        else if(minn == 1) printf("%d
    ",maxx);
        else cout<<maxx<<"/"<<minn<<endl;
        return 0;
    }
  • 相关阅读:
    [LOJ#6284.数列分块入门8] ODT(珂朵莉树)解法
    [CF Contest] Sum of Round Numbers 题解
    基础数论记录
    [CF Contest] Kana and Dragon Quest game 题解
    hexo上怎么写博客
    keepalived的部署
    python局部和全局变量
    python发送邮件
    lamp架构的部署
    rayns数据同步
  • 原文地址:https://www.cnblogs.com/kls123/p/9346166.html
Copyright © 2020-2023  润新知