zoukankan      html  css  js  c++  java
  • UVa 10537

    题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=1478&mosmsg=Submission+received+with+ID+26584073

    每进入村庄或城镇都要收费,已知到要运送到终点的费用,很自然地想到从终点向起点逆推。

    逆推的过程类似 (dijstra),每次选出已知收费最少的点进行扩展,重点在于路径收费的计算,可以用数学推式子,也可以二分,最后从起点向后输出字典序最小的路径即可,在路径上的点满足 (d[v] == d[u] + w)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll, int> pii;
    
    const int maxn = 105;
    const ll INF = 1ll << 60ll;
    
    int n, m;
    vector<int> G[maxn];
    
    ll P;
    ll g[maxn][maxn];
    
    int ID(char ch){
    	if(ch >= 'A' && ch <= 'Z') return ch - 'A' + 1; 
    	else return 26 + ch - 'a' + 1;
    } 
    
    ll get(ll left){
    	ll L = left, R = INF;
    	ll res;
    	while(L <= R){
    		ll mid = (L + R) >> 1;
    		ll fre = mid / 20ll;
    		if(mid % 20ll != 0) ++fre;
    		if(mid - fre >= left){
    			R = mid - 1ll;
    			res = mid;
    		} else if(mid - fre < left){
    			L = mid + 1ll;
    		}
    	}
    	return res - left;
    }
    
    ll d[maxn];
    void dij(int S){
    	priority_queue<pii, vector<pii>, greater<pii> > q;
    	
    	for(int i = 1 ; i <= 52 ; ++i) d[i] = INF;
    	d[S] = P;
    	
    	q.push(pii(d[S], S));
    	
    	while(!q.empty()){
    		pii p = q.top(); q.pop();
    		int u = p.second;
    		if(d[u] != p.first) continue;
    		
    		for(int i = 0 ; i < G[u].size() ; ++i){
    			int v = G[u][i];
    			if(u <= 26){ // town 
    				ll val = get(d[u]);
    				g[v][u] = val;
    				if(d[v] > d[u] + val){
    					d[v] = d[u] + val;
    					q.push(pii(d[v], v));
    				}
    			} else{ // village
    				g[v][u] = 1ll;
    				if(d[v] > d[u] + 1ll){
    					d[v] = d[u] + 1ll;
    					q.push(pii(d[v], v));
    				}
    			}
    		}
    	}
    }
    
    vector<char> path;
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	char uu[10], vv[10];
    	char s[10], t[10];
    	int kase = 0;
    	while(scanf("%d", &n) == 1 && n != -1){
    		memset(g, 0, sizeof(g));
    		path.clear();
    		for(int i = 1 ; i <= 52 ; ++i) G[i].clear();
    		for(int i = 1 ; i <= n ; ++i){
    			scanf("%s%s", uu, vv);
    			G[ID(uu[0])].push_back(ID(vv[0]));
    			G[ID(vv[0])].push_back(ID(uu[0]));
    		}
    		scanf("%lld%s%s", &P, s, t);
    		
    		dij(ID(t[0]));
    		
    		printf("Case %d:
    ", ++kase);
    		printf("%lld
    ", d[ID(s[0])]);
    		
    		int cur = ID(s[0]);
    		while(1){
    			path.push_back((cur <= 26) ? cur + 'A' - 1 : cur - 26 + 'a' - 1);
    			if(cur == ID(t[0])) break;
    			int tmp = 101;
    			for(int i = 0 ; i < G[cur].size() ; ++i){
    				int v = G[cur][i];
    				if(d[cur] == d[v] + g[cur][v]){
    					tmp = min(tmp, v);
    				}
    			} 
    			cur = tmp;
    		} 
    		int tt = 0;
    		for(auto u : path){
    			if(tt) printf("%c", '-');
    			tt = 1;
    			printf("%c", u);
    		} printf("
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Viewer.js 图片预览插件使用
    SqlServer关于“无法删除数据库 "XXXX",因为该数据库当前正在使用”问题的解决方案
    MySQL数据类型详解
    Node.js安装详细步骤教程(Windows版)
    RGB颜色查询对照表
    HTML加载FLASH(*.swf文件)详解
    Cesium区分单击【LEFT_CLICK】和双击事件【LEFT_DOUBLE_CLICK】
    SpringBoot访问jsp页面
    Servlet详解
    Session的生命同期
  • 原文地址:https://www.cnblogs.com/tuchen/p/15026585.html
Copyright © 2011-2022 走看看