zoukankan      html  css  js  c++  java
  • 洛谷p3778[APIO2017]商旅

    【洛谷p3778】【APIO2017】商旅

    题面

    洛谷

    题解

    01分数规划水题...
    设总收益为(x)总代价为(y),那么题目中求的就是(frac{x}{y}<=z)的最小取值。
    把这个式子变个形:(x-yz<=0),然后二分(z)
    我们可以(O(n^3))预处理出最大收益(pro_{i,j})和这张图每2个点之间的最短耗时(其实就是最短路)(d_{i,j})
    然后连边(d_{i,j}*z-pro_{i,j})(spfa)判一下负环即可。

    代码

    #include <bits/stdc++.h>
    
    typedef long double db;  
    const db eps = 1e-9;
    const int maxn = 110;
    const int maxk = 1010;
    const int inf = 0x3f3f3f3f;   
    
    template<class t> inline void read(t& res) {
    	res = 0;  char ch = getchar();  bool neg = 0;
    	while(!isdigit(ch))
    		neg |= ch == '-', ch = getchar();
    	while(isdigit(ch))
    		res = (res << 1) + (res << 3) + (ch & 15), ch = getchar();
    	if(neg)
    		res = -res;  
    }
    inline void cmin(int& a,int b) {
    	if(a > b)
    		a = b;
    }
    inline void cmax(int& a,int b) {
    	if(a < b)
    		a = b;    
    }
    
    int S[maxk][maxk], B[maxk][maxk];  
    int pro[maxk][maxk], d[maxn][maxn], cnt[maxn];  
    int hd[maxn], ver[maxn * maxn], nxt[maxn * maxn];  db wei[maxn * maxn];    
    db dis[maxn];  bool vis[maxn];  
    int n, m, i, j, k, K, cnte;
    
    inline bool equal(db a,db b) { return b - a < eps; }
    inline void adde(int u,int v,db w) {
    	ver[++cnte] = v;  wei[cnte] = w;   
    	nxt[cnte] = hd[u];  hd[u] = cnte;  
    }
    
    inline bool check(db mid) {
    	std::queue<int> q;
    	memset(hd,-1,sizeof(hd));  cnte = 0;
    	while(!q.empty())
    		q.pop();
    	for(int i = 1;i <= n;i++)
    		for(int j = 1;j <= n;j++)
    			if(d[i][j] != inf && i != j)
    				adde(i,j,d[i][j] * mid - pro[i][j]);
    	for(int i = 1;i <= n;i++)
    		q.push(i), dis[i] = 0, vis[i] = 1, cnt[i] = 1;
    	while(!q.empty()) {
    		int u = q.front();  q.pop();  vis[u] = 0;     
    		if(cnt[u] > n)
    			return 1;
    		for(int i = hd[u];~i;i = nxt[i]) {
    			int v = ver[i];  db w = wei[i];   
    			if(dis[u] + w < dis[v]) {
    				dis[v] = dis[u] + w;  
    				if(!vis[v]) {
    					vis[v] = 1;
    					cnt[v]++;
    					q.push(v);
    				}
    			}
    		}
    	}
    	return 0;      
    }
    
    int main() {
    	read(n);  read(m);  read(K);
    	for(int i = 1;i <= n;i++)
    		for(int j = 1;j <= K;j++)
    			read(B[i][j]), read(S[i][j]);  K++;    
    	for(int i = 1;i <= n;i++)
    		for(int j = 1;j <= n;j++)	
    			for(int k = 1;k <= K;k++)
    				if(~S[j][k] && ~B[i][k])
    					cmax(pro[i][j],S[j][k] - B[i][k]);     
    	memset(d,0x3f,sizeof(d));  
    	for(int i = 1, u, v, w;i <= m;i++) {
    		read(u);  read(v);  read(w);
    		d[u][v] = w;   
    	}
    	for(int i = 1;i <= n;i++)
    		d[i][i] = 0;
    	for(int k = 1;k <= n;k++)
    		for(int i = 1;i <= n;i++)
    			for(int j = 1;j <= n;j++)
    				cmin(d[i][j],d[i][k] + d[k][j]);  	
     	db l = 0, r = 1e9;		
    	while(!equal(l,r)) {
    		db mid = (l + r) / 2.0;   
    		if(check(mid))
    			l = mid;
    		else
    			r = mid;
    	}
    	printf("%d
    ",(int)(floor(r)));
    	return 0;  
    }
    
  • 相关阅读:
    扩展知识
    day61——多表操作(增、删除、改、基于对象的跨表查询)
    day60——单表操作补充(批量插入、查询、表结构)
    day59——orm单表操作
    day58——模板继承、组件、自定义标签和过滤器、inclusion_tag、静态文件配置、url别名和反向解析、url命名空间
    day57——视图、模板渲染
    WARNING: Ignoring invalid distribution -ip
    Python- 【python无法更新pip】提示python.exe: No module named pip
    Anaconda Prompt 切换路径不能进入D盘
    Failed calling sys.__interactivehook__ 错误的解决
  • 原文地址:https://www.cnblogs.com/Sai0511/p/11264122.html
Copyright © 2011-2022 走看看