zoukankan      html  css  js  c++  java
  • 【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;
    }
  • 相关阅读:
    console.dir()和console.log()的区别
    md5
    sorket is closed
    箱形图和小提琴图
    PCA降维
    模式识别与机器学习(二)
    模式识别与机器学习(一)
    论文研读Unet++
    分类中使用的一些评价指标
    前列腺分割论文
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6786261.html
Copyright © 2011-2022 走看看