【POJ3621】Sightseeing Cows 分数规划

【POJ3621】Sightseeing Cows

题意:在给定的一个图上寻找一个环路,使得总欢乐值(经过的点权值之和)/ 总时间(经过的边权值之和)最大。

题解:显然是分数规划,二分答案ans,将每条边的权值变成(ans*边权-2*起始点点权),然后我们希望找出一个环,使得环上的总边权<0

(一开始我把题意理解错了,题中给的是单向边,我把它当成是双向边+每条边只能走一次了~,想出一堆做法都接连pass掉)

然后就直接用SPFA判负环就好了嘛!由于原图不一定联通,所以一开始就把所有点都入队就完事了

#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
int n,m,cnt;
int f[1010],to[10010],next[10010],head[1010];
int pa[5010],pb[5010],pt[5010],len[1010],inq[1010];
double dis[1010],val[10010];
queue<int> q;
void add(int a,int b,double c)
{
	to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
int solve(double sta)
{
	memset(head,-1,sizeof(head));
	memset(len,0,sizeof(len));
	cnt=0;
	int i,u;
	for(i=1;i<=m;i++)	add(pa[i],pb[i],sta*pt[i]-f[pa[i]]);
	while(!q.empty())	q.pop();
	for(i=1;i<=n;i++)	q.push(i),dis[i]=0.0,len[i]=1;
	while(!q.empty())
	{
		u=q.front(),q.pop(),inq[u]=0;
		for(i=head[u];i!=-1;i=next[i])
		{
			if(dis[to[i]]>dis[u]+val[i]+1e-4)
			{
				dis[to[i]]=dis[u]+val[i];
				len[to[i]]=len[u]+1;
				if(len[to[i]]>n)	return 1;
				if(!inq[to[i]])
				{
					inq[to[i]]=1;
					q.push(to[i]);
				}
			}
		}
	}
	return 0;
}
int main()
{
	scanf("%d%d",&n,&m);
	int i,a,b,c;
	double l=0.0,r=0.0,mid;
	for(i=1;i<=n;i++)	scanf("%d",&f[i]),r=max(r,1.0*f[i]);
	for(i=1;i<=m;i++)	scanf("%d%d%d",&pa[i],&pb[i],&pt[i]);
	while(r-l>1e-4)
	{
		mid=(l+r)*0.5;
		if(solve(mid))	l=mid;
		else	r=mid;
	}
	printf("%.2f",l);
	return 0;
}
时间: 2024-08-05 11:11:52

【POJ3621】Sightseeing Cows 分数规划的相关文章

poj3621 Sightseeing Cows --- 01分数规划

典型的求最优比例环问题 参考资料: http://blog.csdn.net/hhaile/article/details/8883652 此题中,给出每个点和每条边的权值,求一个环使 ans=∑点权/∑边权 最大. 因为题目要求一个环,而且必然是首尾相接的一个我们理解的纯粹的环,不可能是其他样子的环, 所以我们可以把一条边和指向的点看做整体处理. 上面方程可以化为:ans×e[i]-p[i]=0 以它为边权二分答案,spfa求负环,有负环则该ans可行,增大下界. 若一直不可行,则无解. #i

01分数规划+spfa判负环 POJ3621 Sightseeing Cows

Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10348   Accepted: 3539 Description Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big city! The cows must decide how best to

POJ3621 Sightseeing Cows 最优比率环 二分法

题目链接:http://poj.org/problem?id=3621 Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10552   Accepted: 3613 Description Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big ci

poj3621 Sightseeing Cows

01分数规划 二分+spfa负环(SLF优化) #include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,m; double p[1100]; struct edge{int x,y;double d;}e[5100]; st

POJ3621 Sightseeing Cows【最短路】

题目大意:在一个无向图里找一个环,是的点权和除以边权和最大 思路:UVA11090姊妹题 事实上当这题点权和都为1时就是上一题TUT #include <stdio.h> #include <iostream> #include<queue> #include <string.h> #include <algorithm> #define maxn 10009 #define maxm 10001 #define esp 0.001 using

[转]01分数规划算法 ACM 二分 Dinkelbach 最优比率生成树 最优比率环

01分数规划 前置技能 二分思想最短路算法一些数学脑细胞?问题模型1 基本01分数规划问题 给定nn个二元组(valuei,costi)(valuei,costi),valueivaluei是选择此二元组获得的价值(非负),costicosti是选择此二元组付出的代价(非负),设xi(xi∈{0,1})xi(xi∈{0,1})代表第ii个二元组的选与不选,最大(小)化下式 maximize(or minimize)   r=∑valuei?xi∑costi?ximaximize(or minim

poj 3621 Sightseeing Cows(最优比例生成环,01分数规划)

http://poj.org/problem?id=3621 大致题意:给出一个有向图,每个点都有一个点权,每条有向边也都有一个边权,要求出一个环使得环中点权之和与边权之和的比值最大. 思路:和最优比率生成树异曲同工.设点权是v[i],边权是e[i].不同的是这里一个是点,一个是边.怎么像生成树一样把这两个值放到一起呢?可以把他们都转化到边上.同样的二分λ,每次给边重新赋权为v[i] - λ*e[i](v[i]是该边终点的点权).因为要求比值最大,那么在这前提下于图中的所有环都<=0, 所以我们

POJ 3621 Sightseeing Cows 最大密度环 01分数规划

最大密度环 01分数规划 首先的一个结论就是,不会存在环套环的问题,即最优的方案一定是一个单独的环,而不是大环套着小环的形式.这个的证明其实非常的简单,大家可以自己想一下(提示,将大环上的收益和记为x1,花费为y1,小环上的为x2,y2.重叠部分的花费为S.表示出来分类讨论即可).有了这个结论,我们就可以将花费和收益都转移到边上来了,因为答案最终一定是一个环,所以我们将每一条边的收益规定为其终点的收益,这样一个环上所有的花费和收益都能够被正确的统计. 解决了蛋疼的问题之后,就是01分数规划的部分

POJ 3621 Sightseeing Cows 【01分数规划+spfa判正环】

题目链接:http://poj.org/problem?id=3621 Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11526   Accepted: 3930 Description Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big ci