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;    
    }
  • 相关阅读:
    Yum源的优先级
    history设置时间戳
    ntopng网络流量实时监控
    Filezilla开源FTP传输工具
    红黑树从头至尾插入和删除结点的全程演示图
    清晰理解红黑树的演变---红黑的含义
    ConcurrentHashMap的JDK1.8实现
    linux常用命令
    Java类加载过程
    MySQL存储引擎--MyISAM与InnoDB区别
  • 原文地址:https://www.cnblogs.com/invoid/p/5601803.html
Copyright © 2011-2022 走看看