UVA 10537 The Toll! Revisited 过路费(最短路,经典变形)
2015-07-24 21:00
465 查看
题意:给一个无向图,要从起点s运送一批货物到达终点e,每个点代表城镇/乡村,经过城镇需要留下(num+19)/20的货物,而经过乡村只需要1货物即可。现在如果要让p货物到达e,那么从起点出发最少要准备多少货物?输出答案和路径(多条路径则必须输出字典序最小的)。注:终点需要花费,而起点不需要。
思路:这最短路变形的不错。要逆推过来求最短路径,那么就从e出发到s的距离!只是p比较大,而且城镇还得推出前一站到底需要多少货物,既然直接计算那么麻烦,也可以一直p++直到能留下p为止就推出来了;而乡村就容易推了,只是+1。但是还有个字典序要解决,则在碰到dist[u]==dist[v]+距离的时候就比较一下字典序谁小就记谁。
有一点别忘了,这是在逆推!!所以你要用出发点去更新终点时,要以出发点的dist来比较字典序。无向边是要建两条有向的,防止重边。
AC代码
思路:这最短路变形的不错。要逆推过来求最短路径,那么就从e出发到s的距离!只是p比较大,而且城镇还得推出前一站到底需要多少货物,既然直接计算那么麻烦,也可以一直p++直到能留下p为止就推出来了;而乡村就容易推了,只是+1。但是还有个字典序要解决,则在碰到dist[u]==dist[v]+距离的时候就比较一下字典序谁小就记谁。
有一点别忘了,这是在逆推!!所以你要用出发点去更新终点时,要以出发点的dist来比较字典序。无向边是要建两条有向的,防止重边。
#include <bits/stdc++.h> #define LL long long #define pii pair<int,int> #define INF 0x7f7f7f7f using namespace std; const int N=200; int n, m, l, edge_cnt; LL p; vector<int> vect ; struct node { int from, to; node(){}; node(int from,int to):from(from),to(to){}; }edge[100000]; void add_node(int from,int to) { edge[edge_cnt]=node(from, to); vect[from].push_back(edge_cnt++); } LL dist ; int path , vis ; LL dijkstra(int s,int e) { memset(path, 0, sizeof(path)); memset(vis, 0, sizeof(vis)); memset(dist, 0x7f, sizeof(dist)); priority_queue<pii,vector<pii>,greater<pii> > que; que.push(make_pair(p,s)); dist[s]=p; while(!que.empty()) { int x=que.top().second;que.pop(); if(vis[x]) continue; vis[x]=1; bool flag=isupper(x); //大写,花费多的 LL t=dist[x]+(dist[x]+19)/20; while(t-(t+19)/20<dist[x]) t++; //注意不要超时 for(int i=0; i<vect[x].size(); i++) { node e=edge[vect[x][i]]; if( flag ) { if(dist[e.to]>=t) { if(dist[e.to]==t) { if( x<edge[path[e.to]].from ) path[e.to]=vect[x][i]; //字典序 } else path[e.to]=vect[x][i]; dist[e.to]=t; que.push(make_pair(dist[e.to],e.to)); } } else { if(dist[e.to]>=dist[x]+1) { if(dist[e.to]==dist[x]+1) { if( x<edge[path[e.to]].from ) path[e.to]=vect[x][i]; //字典序 } else path[e.to]=vect[x][i]; dist[e.to]=dist[x]+1; que.push(make_pair(dist[e.to],e.to)); } } } } return dist[e]; } void cal(int s,int e) { cout<<dijkstra(s,e)<<endl; vector<char> ans; int ed=e; while(ed!=s) { ans.push_back( ed ); int t=path[ed]; ed=edge[t].from; } ans.push_back(s); printf("%c",ans[0]); for(int i=1; i<ans.size(); i++) printf("-%c",ans[i]); cout<<endl; } int main() { freopen("input.txt", "r", stdin); char a, b; int j=0; while(scanf("%d", &n), n>=0) { edge_cnt=0; memset(edge,0,sizeof(edge)); for(int i=0; i<N; i++) vect[i].clear(); int up=0; for(int i=0; i<n; i++) { getchar(); scanf("%c %c",&a,&b); //%c会接收到换行!! add_node(a, b); add_node(b, a); } scanf("%lld %c %c",&p, &a, &b); printf("Case %d:\n",++j); cal(b, a); } return 0; }
AC代码
相关文章推荐
- kvc和字典在创建键值对时的相同与区别(setValue forKey )(setObject forKey)
- 从本地或者网络读取图片,并转换为Bitmap图片
- Java常用知识(长期更新)
- java多线程学习笔记(1)——基本概念介绍
- 1002. 写出这个数
- HDU oj 开门人与关门人
- 光流
- 【leetcode】Power of Two
- Hdu 5303 Delicious Apples 2015 Multi-University Training Contest 2
- c语言程序 分支结构
- 线性回归的正规方程解法与梯度下降解法的代码
- 2015 HUAS Summer Training#2 C
- ZOJ 3726 RMQ + 二分法
- C++第一节:类、对象、构造函数、setget
- android-view
- Permutations II
- poj2342.Anniversary party(树形dp)
- Hdu5303 Delicious Apples 贪心
- struts2 模型分配问题和延迟加载问题
- cocos2d-x 3.4 VS2013无法打开包含文件extensions/ExtensionExport.h