zoukankan      html  css  js  c++  java
  • H

    - 题目大意

         给你一个有向图,问你定义一个环的平均值为这个环上所有边的平均值,问你最小的环的平均值是多少。

    - 解题思路

        先利用spfa来判断负环,然后用二分去判断若当前的二分值是mid,让所有的边都减去这个值,如果此时图中出现负环,则说明有环的平均值比这个更小。

    - 代码

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<cstring>
    using namespace std;
    const int N=500;
    const int M=1e6+5;
    const int INF=0x3f3f3f;
    int n,m;
    struct edge {
        int v,next;
        double w;
    }e[M*2];
    int head[N], cnt;
    double d[N];
    int inq[N];
    int cn[N];
    void init ()
    {
        cnt=0;
        memset(head,-1,sizeof(head));
    }
    void addedge(int u,int v,double c)
    {
        e[cnt].w=c;
        e[cnt].v=v;
        e[cnt].next=head[u];
        head[u]=cnt++;
    }
    bool SPFA(int s) {
        memset(d, INF, sizeof(d));
        memset(inq, 0, sizeof(inq));
        memset(cn, 0, sizeof(cn));
        queue<int> Q;
        Q.push(s);
        d[s] = 0;
        inq[s] = 1;
        while(Q.size()) {
            int u = Q.front();
            Q.pop();
            inq[u] = 0;
            for(int i = head[u]; ~i; i = e[i].next)
            {
                int v = e[i].v;
                double w = e[i].w;
                if(d[v] > d[u] + w)
                {
                    d[v] = d[u] + w;
                    if(!inq[v])
                    {
                        Q.push(v);
                        inq[v] = 1;
                        if(++cn[v] >= n)
                            return false;
                    }
                }
            }
        }
        return true;
    }
    
    bool check(double x)
    {
        bool vis=false;
        for(int i=1;i<=n;i++)
        {
            for(int j=head[i];j!=-1;j=e[j].next)
                e[j].w-=x;
        }
        for(int i=1;i<=n;i++)
        {
            if(!SPFA(i))
                vis=true;
        }
         for(int i=1;i<=n;i++)
        {
            for(int j=head[i];j!=-1;j=e[j].next)
                e[j].w+=x;
        }
        return vis;
    }
    
    int main()
    {
        int t,a,b;
        double c;
        scanf("%d",&t);
        for(int k=1;k<=t;k++)
        {
            double l=INF,r=0,mid;
            init();
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%lf",&a,&b,&c);
                addedge(a,b,c);
                l=min(l,c);
                r=max(r,c);
            }
            printf("Case #%d: ",k);
            if(!check(r+1))
                 printf("No cycle found.
    ");
            else
            {
                while(r-l>1e-8)
                {
                    mid=(r+l)/2;
                    if(check(mid))
                        r=mid;
                    else
                        l=mid;
                }
                printf("%.2lf
    ",r);
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    解决前端跨域请求的几种方式
    使用excel 展现数据库内容
    win7 安装windows 服务 报错 System.Security.SecurityException 解决方法 An exception occurred during the Install phase. System.Security.SecurityException: The so
    java 查看线程死锁
    linux 配置 java 环境变量
    数据库性能优化
    C#中静态与非静态方法比较
    apache日志切割工具cronolog安装配置
    虚拟机克隆后网卡有问题解决方法
    vs2015工具箱突然没有了
  • 原文地址:https://www.cnblogs.com/alpacadh/p/8449749.html
Copyright © 2011-2022 走看看