zoukankan      html  css  js  c++  java
  • bzoj 1050

    一条从S到T的路径的答案为MAX/MIN。

    无法直接获得最优解。

    所有边按边权从大到小排序,从大到小枚举MIN,要MAX尽量小。

    问题变成给你i条无向边,使S与T联通且使边权的最大值最小。

    这不就是最小生成树的性质吗?Kruskal算法。

    从后往前枚举每一条边,如果边连接的两个节点不在同一集合,就合并,直到S与T在同一集合。

    最小的MAX即是枚举到的最后一条边。

    交叉相乘更新答案。用辗转相除法把答案变成既约分数。

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    int read(){
        char c; while(!isdigit(c=getchar())); int x=c-'0';
        while(isdigit(c=getchar())) x=x*10+c-'0'; return x;
    }
    struct edge{
        int u,v,d;
    }e[5001];
    bool cmp(edge x,edge y){
        return x.d>y.d;
    }
    int fa[501];
    int find(int x){
        return x==fa[x]? x:fa[x]=find(fa[x]);
    }
    int gcd(int x,int y){
        return y==0? x:gcd(y,x%y);
    }
    int main(){
        int n=read(),m=read();
        for(int i=1;i<=m;i+=1)
            e[i].u=read(),e[i].v=read(),e[i].d=read();
        sort(e+1,e+m+1,cmp);
        int s=read(),t=read(),res1=0,res2=0;
        for(int i=1;i<=m;i+=1){
            int ans=0;
            for(int j=1;j<=n;j+=1) fa[j]=j;
            for(int j=i;j>=1;j-=1){
                int x=find(e[j].u),y=find(e[j].v);
                if(x!=y) fa[x]=y;
                if(find(s)==find(t)){
                    ans=e[j].d; break;
                }
            }
            if(ans)
                if((!res1 && !res2) || res1*e[i].d>res2*ans){
                    int x=gcd(e[i].d,ans);
                    res1=ans/x; res2=e[i].d/x;
                }
        }
        if(!res1 && !res2) puts("IMPOSSIBLE");
        else if(res1%res2) printf("%d/%d",res1,res2); 
        else printf("%d",res1/res2);
        return 0;
    }
  • 相关阅读:
    产品化软件开发与项目化软件开发的对比
    4.ThinkPHP 3.1.2 输出和模型使用
    ThinkPHP 3.1.2 输出和模型使用1
    事务管理配置与@Transactional注解使用
    logstash 区分多个文件index端配置
    logstash 读取多个系统相同文件shipper端
    centos 6.5安装git
    如何查看PHP的配置信息
    MVC模式和URL访问
    1.环境搭建
  • 原文地址:https://www.cnblogs.com/AmnesiacVisitor/p/7657577.html
Copyright © 2011-2022 走看看