BZOJ 1486: [HNOI2009]最小圈 分数规划

时空隧道


分析:
其实就分数规划来讲这道题很简单….
重点是判负环…
一般的spfa判负环一定会TLE,看看数据范围就知道了…
怎么办呢…可以dfs判负环,但是还是会TLE…
怎么办啊…
有一个机智的办法,反正我们都是判负环,为什么还要把dis赋成inf呢,干脆赋成0好了…正确是显然的…时间复杂度呢…递归层数减少了…只有变成负数的时候才会去递归…所以从10sTLE变成了128msAC…


代码如下:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
//by NeighThorn
#define inf 100000000000
using namespace std;
//长眉连娟,微睇绵藐,色授魂与,心愉于侧 
const int maxn=3000+5,maxm=10000+5;
int n,m,hd[maxn],to[maxm],nxt[maxm],vis[maxn],tim[maxn],cnt;
double w[maxm],sum,dis[maxn]; 

inline void add(double s,int x,int y){
    w[cnt]=s;to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++;
}

inline bool dfs(int root,double mid){
    vis[root]=1;
    for(int i=hd[root];i!=-1;i=nxt[i])  
        if(dis[to[i]]>dis[root]+w[i]-mid){
            if(vis[to[i]])
                return true;
            dis[to[i]]=dis[root]+w[i]-mid;
            if(dfs(to[i],mid))
                return true;
        }
    vis[root]=0;
    return false;
}

inline bool check(double mid){
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));
    for(int i=1;i<=n;i++)
        if(dfs(i,mid))
            return true;
    return false;
}

signed main(void){
    memset(hd,-1,sizeof(hd));
    scanf("%d%d",&n,&m);
    double s;cnt=sum=0;
    for(int i=1,x,y;i<=m;i++)
        scanf("%d%d%lf",&x,&y,&s),add(s,x,y),sum+=s;
    double l=-inf,r=inf,ans;
    while(r-l>=1e-9){
        double mid=(l+r)/2.0;
        if(check(mid))
            r=mid,ans=mid;
        else
            l=mid;
    }
    printf("%.8f\n",ans);
    return 0;
}

by >_< NeighThorn

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值