poj 3621 0/1分数规划求最优比率生成环
2024-09-02 01:11:39
思路:以val[u]-ans*edge[i].len最为边权,判断是否有正环存在,若有,那么就是ans小了。否则就是大了。
在spfa判环时,先将所有点进队列。
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#define Maxn 1010
#define Maxm 6000
#define inf 1e10
#define eps 1e-4
using namespace std;
int vi[Maxn];
struct Edge{
int u,v,next;
double len;
}edge[Maxm];
double dis[Maxn],val[Maxn];
int head[Maxn],e,n,cnt[Maxn];
void add(int u,int v,double len)
{
edge[e].u=u,edge[e].v=v,edge[e].len=len,edge[e].next=head[u],head[u]=e++;
}
void init()
{
e=;
memset(vi,,sizeof(vi));
memset(cnt,,sizeof(cnt));
memset(head,-,sizeof(head));
}
int spfa(double ans)
{
int i,j,v,u;
queue<int> q;
memset(cnt,,sizeof(cnt));
for(i=;i<=n;i++){
dis[i]=;
q.push(i);
vi[i]=;
}
while(!q.empty()){
int u=q.front();
cnt[u]++;
q.pop();
vi[u]=;
for(i=head[u];i!=-;i=edge[i].next){
v=edge[i].v;
double d=val[u]-ans*edge[i].len;
if(dis[v]<dis[u]+d){
dis[v]=dis[u]+d;
cnt[v]++;
if(cnt[v]>=n) return ;
if(!vi[v]){
q.push(v);
vi[v]=;
}
}
}
}
return ;
}
int main()
{
int i,j,a,b,m;
double c;
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(i=;i<=n;i++)
scanf("%lf",val+i);
for(i=;i<=m;i++){
scanf("%d%d%lf",&a,&b,&c);
add(a,b,c);
}
double l=,r=,mid;
while(r-l>eps){
mid=(l+r)/;
if(spfa(mid))
l=mid;
else
r=mid;
}
printf("%.2lf\n",l);
}
return ;
}
最新文章
- 带你实现开发者头条APP(四)---首页优化(加入design包)
- C++ Base64 编码 解码
- emulator-arm.exe 已停止工作、 emulator-x86 已停止工作
- 使用OrderBy对List<;Person>;集合排序
- 利用序列化的方式实现C#深复制和浅复制
- apache开源项目--Camel
- Android中文乱码彻底解决
- 对于百川SDK签名验证的问题
- 【HDU3341】 Lost&#39;s revenge (AC自动机+状压DP)
- 使用boost中的线程池
- React,关于redux的一点小见解
- 第三节:Creating API Endpoints (创建API路由)
- maven中的传递依赖和传递依赖的解除
- linux内核IDR机制详解【转】
- 学号 20175212童皓桢 《Java程序设计》第8周学习总结
- OO第一阶段纪实
- Calendar获取当前年份、月份、日期
- 数据文件resize扩容
- 【Go命令教程】4. go get
- [Android Pro] AndroidStudio IDE界面插件开发(进阶篇之Action机制)