zoukankan      html  css  js  c++  java
  • 【HNOI2009】最小圈 题解(SPFA判负环+二分答案)

    前言:模拟赛考试题,不会做,写了个爆搜滚蛋仍然保龄。

    ---------------------

    题目链接

    题目大意:给定一张有向图,求一个环,使得这个环的长度与这个环的大小(所含结点个数)的比值最小。输出这个比值,保留8位小数。保证数据有解。

    ---------------------

    转化一下题意。要求是使得$C=frac{sumlimits_{i=1}^k w[i]}{sumlimits_{i=1}^k b[i]},b[i]=1$最小。等式变换,得到$sumlimits_{i=1}^k w[i]-C=0$。我们可以二分这个$C$然后判断有没有负环即可。

    貌似看题解是$01$分数规划,我也不太懂。理论上复杂度是$O(nmlog_2 (r-l))$,不过因为算法比较高效也能卡过去。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=10005;
    const double eps=1e-12;
    int n,m,vis[maxn];
    int head[maxn*2],cnt; 
    struct node
    {
        int next,to;
        double dis;
    }edge[maxn*2];
    double dis[maxn];
    inline void add(int from,int to,double dis)
    {
        edge[++cnt].next=head[from];
        edge[cnt].to=to;
        edge[cnt].dis=dis;
        head[from]=cnt;
    }
    inline bool spfa(int now,double mid)
    {
        vis[now]=1;
        for (int i=head[now];i;i=edge[i].next)
        {
            int to=edge[i].to;
            if (dis[to]>dis[now]+edge[i].dis-mid)
            {
                dis[to]=dis[now]+edge[i].dis-mid;
                if (vis[to]||spfa(to,mid)) return 1;
            }
        }
        vis[now]=0;
        return 0;
    }
    inline bool check(double mid)
    {
        for (int i=1;i<=n;i++) dis[i]=0,vis[i]=0;
        for (int i=1;i<=n;i++) if (spfa(i,mid)) return 1;
        return 0;
    }
    int main()
    {
        cin>>n>>m;
        for (int i=1;i<=m;i++)
        {
            int x,y;double z;cin>>x>>y>>z;
            add(x,y,z);
        }
        double l=-1e7,r=1e7;
        while(r-l>eps)
        {
            double mid=(l+r)/2.0;
            if (check(mid)) r=mid;
            else l=mid;
        }
        printf("%.8lf",r);
        return 0;
    }
  • 相关阅读:
    快速幂 快速乘法
    扩展欧几里得学习笔记
    求逆序数数目(树状数组+离散化)
    隐式图的遍历
    随机数生成
    推倒重来
    动态规划初步
    子集生成
    东大oj1155 等凹函数
    P1278 单词游戏
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/13172884.html
Copyright © 2011-2022 走看看