• BZOJ_1486_[HNOI2009]最小圈_01分数规划


    BZOJ_1486_[HNOI2009]最小圈_01分数规划

    Description

    Input

    Output

    Sample Input

    4 5
    1 2 5
    2 3 5
    3 1 5
    2 4 3
    4 1 3

    Sample Output

    3.66666667
     

    二分答案,边权减去答案,判负环即可。
    然而spfa判负环会T掉,于是我使用了dfs判负环的方法。
    dfs判负环代码:
    void dfs(int x)
    {
        vis[x]=1;
        int i;
        for(i=head[x];i&&!ok;i=nxt[i]){
            if(dis[to[i]]>dis[x]+cost[i]){
                dis[to[i]]=dis[x]+cost[i];
                if(vis[to[i]]){
                    ok=1;return ;
                }
                dfs(to[i]);
            }
        }
        vis[x]=0;
    }
    

    不断更新最小值,直到更新了一圈回来,则说明有负环存在。

    总之是比spfa快到不知哪里去。

    dis数组清零即可。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 3050
    #define M 10050
    #define du double
    #define eps 1e-9
    int head[N],to[M],nxt[M],val[M],cnt,n,m;
    int dep[N],inq[N],Q[N],l,r,ok,vis[N];
    du dis[N],cost[M];
    inline void add(int u,int v,int w)
    {
        to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;val[cnt]=w;
    }
    void dfs(int x)
    {
        vis[x]=1;
        int i;
        for(i=head[x];i&&!ok;i=nxt[i]){
            if(dis[to[i]]>dis[x]+cost[i]){
                dis[to[i]]=dis[x]+cost[i];
                if(vis[to[i]]){
                    ok=1;return ;
                }
                dfs(to[i]);
            }
        }
        vis[x]=0;
    }
    bool check(du x)
    {
        int i;
        for(i=1;i<=m;i++) cost[i]=val[i]-x;
        for(i=1;i<=n;i++) dis[i]=vis[i]=0;
        for(i=1,ok=0;i<=n;i++)
        {
            dfs(i);
            if(ok) return 1;
        }
        return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        int i,x,y,z;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        du L=-100000,R=100000;
        while(R-L>eps)
        {
            du mid=(L+R)*0.5;
            if(check(mid)) R=mid;
            else L=mid;
        }
        printf("%.8lf
    ",L);
    }
    
  • 相关阅读:
    代理模式 值代理
    装饰者模式 检查装饰器循环
    装饰者模式 静态装饰组合
    装饰者模式 在依赖注入中体现
    代理模式 属性代理
    装饰器模式 动态组合装饰
    代理模式 请勿饮酒
    享元模式 文本编辑
    Mysql 字符串字段判断是否包含某个字符串的3种方法
    vuex存储保存数据、使用数据
  • 原文地址:https://www.cnblogs.com/suika/p/8698411.html
Copyright © 2020-2023  润新知