• *


    然后这个题是01分数规划,然而我并miu看出来,然后看了两分钟,happy的写了个floyd,然后成功挂掉。

    这个题然后其实是一个

    设路程数组为dis,时间为tim。
    设一个数组x,x[i] = 1表示第i条边在所选的路线中,x[i] = 0表示第i条边不在路线中,(所以,dis[i],tim[i],为定值,x[i]不是定值,x[i]会随着你跑spfa而变)

    然后我们把式子列出来就是:

    R=(i=1ndis[i]x[i]∑i=1ndis[i]∗x[i])/(i=1ntim[i]x[i]∑i=1ntim[i]∗x[i])

    。。。。他不支持markdown。。。。。。

      当f(L)==0时,(看上面)L就是我们要求的R,就是最优解。

      当f(L)>0时:

     

      那么什么时候f(L) > 0呢?
      有两种情况:
      1、dist[n] > 0:
      上面已经说了,dist[n]就相当于L,所以dist[n] > 0时,L就大于0咯。
      2、存在正环:
      因为本题是跑最长路,如果你找到一个正环,在里面一直绕,当前的权值肯定是非常大的,dist[n]一定大于0。

      然后L就二分答案求一下,注意精度。。。然后就没有然后了。。。。

      

    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef double db;
    const int maxn=20000;
    const db inf=0x7ffffff;
    struct Edge {
    	int f;
    	int to;
    	db d;
    	db tim;
    	int next;
    } edge[maxn];
    int head[maxn],time[maxn];
    db dist[maxn];
    bool vis[maxn];
    int n;
    db dis[150][150],tim[150][150];
    int tot;
    void add(int f,int t,db d,db tt) {
    	edge[++tot].to = t;
    	edge[tot].d = d;
    	edge[tot].tim = tt;
    	edge[tot].next = head[f];
    	head[f] = tot;
    }
    deque<int>q;
    void clr() {
    	tot = 0;
    	while(!q.empty())
    		q.pop_front();
    	for(int i = 1; i <= n; i++)
    		dist[i] = -inf;
    	memset(vis,0,sizeof(vis));
    	memset(time,0,sizeof(time));
    //  printf("%lf
    ",dist[1]);
    }
    bool spfa(db mid) {
    	clr();
    	q.push_front(1);
    	dist[1] = 0.0;
    	while(!q.empty()) {
    		int x = q.front();
    		q.pop_front();
    		vis[x] = 0;
    		for(int i = head[x]; i; i = edge[i].next) {
    			Edge e = edge[i];
    			if(dist[e.to] < dist[x] + (e.d - mid * e.tim)) {
    				dist[e.to] = dist[x] + (e.d - mid * e.tim);
    				if(!vis[e.to]) {
    					vis[e.to] = true;
    					time[e.to]++;
    					if(time[e.to] > n) {
    						return true;
    					}
    					if(!q.empty() && dist[e.to] > dist[q.front()])
    						q.push_front(e.to);
    					else
    						q.push_back(e.to);
    				}
    			}
    		}
    	}
    	if(dist[n] > 0)
    		return true;
    	return false;
    }
    db div() {
    	db l = 0,r = 100000000;
    	db ans = 0;
    	int k = 0;
    	while(k <= 100) {
    		double mid = ((l + r) / (double)(2));
    		if(!spfa(mid))
    			r = mid;
    		else
    			l = mid,ans = max(ans,mid);
    		k ++;
    		//  printf("l:%.1lf r:%.1lf
    ",l,r);
    	}
    	return ans;
    }
    int main() {
    	scanf("%d",&n);
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= n; j++)
    			scanf("%lf",&dis[i][j]);
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= n; j++)
    			scanf("%lf",&tim[i][j]);
    	for(int i = 1; i <= n; i++) {
    		for(int j = 1; j <= n; j++) {
    			if(i != j) {
    				add(i,j,dis[i][j],tim[i][j]);
    			}
    		}
    	}
    	printf("%.3f",div());
    	return 0;
    }
    

      

     

  • 相关阅读:
    PHP配置redis支持
    redis入门——redis常用命令
    CentOS7 linux下yum安装redis以及使用
    Linux安装配置git
    Java基础88 数据库设计的三大范式
    Java基础87 MySQL数据约束
    Java基础85 MVC开发模式
    错误/异常:java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind;的解决方法
    Java基础84 javaBean规范
    Java基础83 JSP标签及jsp自定义标签(网页知识)
  • 原文地址:https://www.cnblogs.com/excellent-zzy/p/11288552.html
Copyright © 2020-2023  润新知