zoukankan      html  css  js  c++  java
  • 最小圈

    试题描述

    考虑带权的有向图 G=(V,E) 以及 w:E→R,每条边 e=(i,j)(i≠j,i∈V,j∈V)的权值定义为 w(i,j),令 n=∣V∣。c=(c1,c2,⋯,ck)(ci∈V)是 G 中的一个圈当且仅当 (ci,ci+1)(1≤i<k)都在 E 中,这时称 k 为圈 c 的长度。同时令 c(k+1)=c,并定义圈 c=(c1,c2,⋯,ck)的平均值为:

    即 c 上所有边的权值的平均值。
    令 μ∗(c)=min{μ(c)}为 G 中所有圈 c 的平均值的最小值。现在的目标是:在给定了一个图 G=(V,E)以及 w:E→R之后,请求出 G 中所有圈 c 的平均值的最小值 μ∗(c)=min{μ(c)}。
    输入
    第一行包含两个正整数 n 和 m,并用一个空格隔开,其中 n=∣V∣,m=∣E∣,分别表示图中有 n 个顶点和 m 条边;
    接下来 m 行,每行包含用空格隔开的三个数 i,j,w(i,j),表示有一条边 (i,j)且该边的权值为w(i,j)。
    输入数据保证图 G=(V,E)连通,存在圈且有一个点能到达其他所有点。
    输出
    仅包含一个实数 μ∗=min{μ(c)},要求输出到小数点后 8 位。
    输入示例
    样例输入
    1 4 5
    1 2 5
    2 3 5
    3 1 5
    2 4 3
    4 1 3
    样例输入 2
    2 2
    1 2 -2.9
    2 1 -3.1
    输出示例
    样例输出 1
    3.66666667
    样例输出 2
    -3.00000000
    其他说明
    数据范围与提示
    对于 20% 的数据,1≤n≤100,1≤m≤1000;
    对于 40%的数据,1≤n≤1000,1≤m≤5000;
    对于 100% 的数据,1≤n≤3000,1≤m≤10^4,∣wi,j∣≤10^7。
    输入保证 1≤i,j≤n。

     第一眼是和WordStrings一个尿性,然而就是一样的

    二分答案加上SPFA

    就很奈斯,然而调的时候把二分写错了,被人打了好久QAQ

    下面给出代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    using namespace std;
    inline int rd(){
        int x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
        return x*f;
    }
    void write(int x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
        return ;
    }
    int n,m;
    int head[1000006],to[1000006],nxt[1000006];
    double c[1000006],v[1000006];
    int total=0;
    void add(int x,int y,double z){
        total++;
        to[total]=y;
        v[total]=z;
        nxt[total]=head[x];
        head[x]=total;
        return ;
    }
    int book[1000006];
    double dis[1000006];
    bool spfa_find_circle(int x,double h){//SPFA判环 
        book[x]=1;
        for(int e=head[x];e;e=nxt[e]){
            if(dis[to[e]]>dis[x]+v[e]-h){//如果更优,就判断是否为环 
                if(book[to[e]]) return true;
                else{
                    dis[to[e]]=dis[x]+v[e]-h;//更新 
                    if(spfa_find_circle(to[e],h)) return true;
                }
            }
        }
        book[x]=0;
        return false;
    }
    bool check(double x){
        for(int i=1;i<=n;i++) dis[i]=book[i]=0;
        bool f=0;
        for(int i=1;i<=n;i++){//枚举起点 
            if(spfa_find_circle(i,x)){
                f=1;
                break;
            }
        }
        return f;
    }
    int main()
    {
        n=rd();
        m=rd();
        double minn=999999999,maxn=-999999999;
        for(int i=1;i<=m;i++){
            int x,y;
            double z;
            x=rd();
            y=rd();
            scanf("%lf",&z);
            add(x,y,z);//选出最大和最小值,开始的时候取得太大了,然后爆了,因为平均数肯定在最大和最小值之间 
            minn=min(minn,z);
            maxn=max(maxn,z);
        }
        double l=minn,r=maxn;
        while(r-l>1e-9){
            double mid=(r+l)/2.0;//写成了(r-l)/2.0 QAQ 
            if(check(mid)) r=mid;
            else l=mid;
        }
        printf("%.8lf",r);
        return 0;
    }
    蒟蒻总是更懂你✿✿ヽ(°▽°)ノ✿
  • 相关阅读:
    Wyn Enterprise报表动态参数的实现
    全功能 Visual Studio 组件集 ComponentOne 2018V2发布,提供轻量级的 .NET BI 仪表板
    葡萄城SpreadJS表格控件荣获“2018年度优秀软件产品”称号
    中国电建:ComponentOne+Spread突破行业桎梏,推动数据产业“智能化”变革
    葡萄城活字格 Web 应用生成平台荣获软博会十佳优秀产品
    石油与天然气行业中数据报表分析
    从容 IT 人生路,开发工具伴我行——“葡萄城 30 周年”征文
    用WijmoJS玩转您的Web应用 —— Angular6
    对抗海量表格数据,【华为2012实验室】没有选择复仇者联盟
    投票最喜欢报表模板,赢取复联3正版玩偶
  • 原文地址:https://www.cnblogs.com/WWHHTT/p/9621701.html
Copyright © 2011-2022 走看看