zoukankan      html  css  js  c++  java
  • bzoj1486: [HNOI2009]最小圈

    二分+dfs。

    这道题求图的最小环的每条边的权值的平均值μ。

    这个平均值是大有用处的,求它我们就不用记录这条环到底有几条边构成。

    如果我们把这个图的所有边的权值减去μ,就会出现负环。

    所以二分求解。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define eps 1e-10
    using namespace std;
    const int maxn = 10000 + 10;
    const int maxm = 200000 + 10;
    int g[maxn],v[maxm],next[maxm],eid;
    double w[maxm],dist[maxn],e[maxm],c;
    bool vis[maxn];
    int n,m;
    
    void addedge(int a,int b,double c) {
        v[eid]=b; w[eid]=c; next[eid]=g[a]; g[a]=eid++;
    }
    
    void build() {
        memset(g,-1,sizeof(g));
        scanf("%d%d",&n,&m);
        for(int i=1,a,b;i<=m;i++) {
            scanf("%d%d%lf",&a,&b,&c);
            addedge(a,b,c);
        }
    }
    
    bool dfs(int u) {
        vis[u]=1;
        for(int i=g[u];~i;i=next[i]) if(dist[v[i]]>dist[u]+e[i]) {
            if(vis[v[i]]) return true;
            dist[v[i]]=dist[u]+e[i];
            if(dfs(v[i])) return true;
        }
        vis[u]=0;
        return false;
    }
    
    bool calc() {
        memset(dist,0,sizeof(dist));
        memset(vis,0,sizeof(vis));    
        for(int i=1;i<=n;i++) if(dfs(i)) return 1;
        return 0;
    }
    
    void solve() {
        double l = -1e9,r=1e9,mid;
        while(r-l>=eps) {
            mid=(l+r)/2;
            for(int u=1;u<=n;u++)
            for(int i=g[u];~i;i=next[i]) 
                e[i]=w[i]+mid;
            if(calc()) l=mid;
            else r=mid;
        }
        printf("%.8lf
    ",-l);
    }
    
    int main() {
        build();
        solve();    
        return 0;    
    }
  • 相关阅读:
    apache性能测试工具
    redis和memcacahe、mongoDB的区别
    redis 安装
    redis介绍
    svn基本命令
    变量
    redis持久化有几种.如何配置
    Sundy_Android开发深入浅出和高级开发视频教程
    VC++ MFC类库基础(55讲全)
    从C++起步到MFC实战VC++软件工程师高端培训 视频保存在 播音员的网盘中
  • 原文地址:https://www.cnblogs.com/invoid/p/5601803.html
Copyright © 2011-2022 走看看