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

裸题...平均权值最小的环....

注意$dfs-spfa$时$dfs(cl)$...不要写成$dfs(u)$

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const int N=3005,M=1e4+5;
const double eps=1e-9;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m,u,v;
double w;
struct edge{
    int v,ne;
    double w;
}e[M];
int h[N],cnt=0;
inline void ins(int u,int v,double w){
    cnt++;
    e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
}
double d[N],g;
int vis[N],cl;
bool dfs(int u){
    vis[u]=cl;
    for(int i=h[u];i;i=e[i].ne){
        int v=e[i].v;double w=e[i].w-g;
        if(d[v]>d[u]+w){
            d[v]=d[u]+w;
            if(vis[u]==vis[v]) return true;
            else if(dfs(v)) return true;
        }
    }
    vis[u]=0;
    return false;
}
bool NegativeCircle(double mid){
    g=mid;
    memset(vis,0,sizeof(vis));
    memset(d,0,sizeof(d));
    for(cl=1;cl<=n;cl++) if(dfs(cl)) return true;
    return false;
}
bool check(double mid){return NegativeCircle(mid);}
void solve(){
    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",l);
}
int main(){
    freopen("in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=m;i++){
        u=read(),v=read();
        scanf("%lf",&w);
        ins(u,v,w);
    }
    solve();
}

 

转载于:https://www.cnblogs.com/candy99/p/6433815.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值