zoukankan      html  css  js  c++  java
  • BZOJ1050 [HAOI2006]旅行comf

    题目描述:

    给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T,求
    一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个
    比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。
     
    题解:
    我们想如何贪心。
    既然要比值最小,那么我们找到尽量小的最大边和尽量大的最小边就行了。
    那怎么找呢?
    我们将每个边权排序,每次枚举最小边和最大边,并将其加入并查集,如果将起点和中点连在了同一个联通块中,就是符合答案的一组解了。
    附上代码:
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m,s,t,f[5001],flag,idx,cnt1,cnt2;
    double ans=999999999.0;
    struct Edge
    {
        int l,r,v;
    }a[5001];
    bool cmp(const Edge &x,const Edge &y)
    {
        return x.v<y.v;
    }
    int find(int p)
    {
        if(f[p]!=p)
            f[p]=find(f[p]);
        return f[p];
    }
    void merge(int x,int y)
    {
        int fx=find(x);
        int fy=find(y);
        if(fx!=fy)
            f[fx]=fy;
    }
    int gcd(int x,int y)
    {
        if(x%y==0)
            return y;
        return gcd(y,x%y);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].v);
        scanf("%d%d",&s,&t);
        sort(a+1,a+m+1,cmp);
        for(int i=1;i<=m;i++)
        {
            flag=0;
            for(int j=1;j<=n;j++)
                f[j]=j;
            for(int j=i;j<=m;j++)
            {
                merge(a[j].l,a[j].r);
                if(find(s)==find(t))
                {
                    idx=j;
                    flag=1;
                    break;
                }
            }
            if(flag==1)
            {
                if(ans>(a[idx].v*1.0)/a[i].v)
                {
                    ans=(a[idx].v*1.0)/a[i].v;
                    cnt1=a[idx].v;
                    cnt2=a[i].v;
                }
            }
        }
        if(ans==999999999.0)
        {
            printf("IMPOSSIBLE");
            return 0;
        }
        int k=gcd(cnt1,cnt2);
        if(cnt2/k==1)
            printf("%d",cnt1/k);
        else
            printf("%d/%d",cnt1/k,cnt2/k);
    }
  • 相关阅读:
    2020 CCF CSP-J2(表达式)
    PSP总结报告
    第十三周例行报告
    对团队成员公开感谢博客
    作业要求 20181127-1 附加作业 软件工程原则的应用实例分析
    第十二周例行报告
    第十一周例行报告
    第十周例行报告
    第八周例行报告
    第七周例行报告
  • 原文地址:https://www.cnblogs.com/jiangminghong/p/9843204.html
Copyright © 2011-2022 走看看