【bzoj1486】【HNOI2009】【最小圈】【分数规划】

本文介绍了一种结合分数规划与SPFA算法判断负权回路的方法,并提供了完整的C++实现代码。该方法适用于解决特定类型的最优化问题,在图论中具有广泛的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

题解:分数规划+spfa判负环。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 3010
#define M 10010
#define exp 1e-9
using namespace std;
struct use{int en;double v,w;}e[M];
int point[N],next[M],cnt,x,y,vis[N],p,n,m;
double v,l,r,dis[N];
void add(int x,int y,double v){  
  next[++cnt]=point[x];point[x]=cnt;
  e[cnt].en=y;e[cnt].w=e[cnt].v=v;
}
void build(double x){
  for (int i=1;i<=n;i++)
   for (int j=point[i];j;j=next[j])
     e[j].v=e[j].w-x;
}
void spfa(int x){
  vis[x]=1;
  for (int i=point[x];i;i=next[i])
   if (dis[e[i].en]>dis[x]+e[i].v){
     if (vis[e[i].en]){p=1;return;}
     else {dis[e[i].en]=dis[x]+e[i].v;spfa(e[i].en);}
    }
  vis[x]=0;
}
bool check(){
  memset(dis,127/3,sizeof(dis));memset(vis,0,sizeof(vis));p=0;
  for (int i=1;i<=n;i++){spfa(i);if (p) return true;}
  return false;
}
int main(){
  scanf("%d%d",&n,&m);
  for (int i=1;i<=m;i++){scanf("%d%d%lf",&x,&y,&v);add(x,y,v);}  
  l=-1000000000;r=1000000000;
  while (r-l>exp){
   double mid=(l+r)/2;build(mid);
   if (check()) r=mid;else l=mid;
  }
  printf("%.8lf",l);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值