uva 10537 Toll! Revisited(优先队列优化dijstra及变形)
大致题意:有两种节点,一种是大写字母,一种是小写字母。
首先输入m条边。当经过小写字母时须要付一单位的过路费。当经过大写字母时,要付当前財务的1/20做过路费。
问在起点最少须要带多少物品使到达终点时还有k个物品。
当有多条符合条件的路径时输出字典序最小的一个。
思路:已知终点的权值,那么能够从终点向前推。
求终点到起点的最短路径,然后按字典序打印路径。
比較难处理的是:向前推时前驱节点的权值计算。列个方程算算就能够了,主要时不能整除的情况。
计算前驱结点dis值的时候,同一时候记录(i,j)的边权值。这是打印路径的根据。
#include <stdio.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <stack>
#include <queue>
#define LL long long
#define _LL __int64 using namespace std;
const int INF = 0x3f3f3f3f;
const int maxm = 1010;
const int maxn = 60; struct node
{
int v,w;
int next;
}edge[maxm]; int m;
int pre[maxn],cnt;
int start,end;
LL dis[maxn],p;
int vis[maxn];
vector <int> ans; void init()
{
cnt = 0;
memset(pre,-1,sizeof(pre));
for(int i = 0; i < maxm; i++)
edge[i].w = 0;
} void add(int u, int v)
{
edge[cnt].v = v;
edge[cnt].next = pre[u];
pre[u] = cnt++;
} void dijstra()
{
priority_queue <pair<LL,int>, vector<pair<LL,int> >, greater<pair<LL,int> > > que;
while(!que.empty()) que.pop();
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis)); dis[end] = p; que.push(make_pair(dis[end],end)); while(!que.empty())
{
int u = que.top().second;
que.pop();
if(vis[u]) continue;
vis[u] = 1; for(int i = pre[u]; i != -1; i = edge[i].next) //松弛相邻节点
{
if(vis[edge[i].v]) continue;
int v = edge[i].v; if(u < 26)
{
//计算前驱结点的权值,推断是否整除,若不整除,尝试加1继续推断
if(dis[u]%19 == 0)
{
if(dis[v] > dis[u]/19*20)
{
dis[v] = dis[u]/19*20;
edge[i].w = edge[i^1].w = dis[v]-dis[u];
que.push(make_pair(dis[v],v));
}
}
else if( (dis[u]+1)%19 )
{
if(dis[v] > (dis[u]+1)*20/19)
{
dis[v] = (dis[u]+1)*20/19;
edge[i].w = edge[i^1].w = dis[v]-dis[u];
que.push(make_pair(dis[v],v));
}
}
else
{
if(dis[v] > (dis[u]+1)*20/19-1 )
{
dis[v] = (dis[u]+1)*20/19-1;
edge[i].w = edge[i^1].w = dis[v]-dis[u];
que.push(make_pair(dis[v],v));
}
}
}
else
{
if(dis[v] > dis[u]+1)
{
dis[v] = dis[u]+1;
edge[i].w = edge[i^1].w = 1;
que.push(make_pair(dis[v],v));
}
} }
}
} void solve()
{
ans.clear();
int now;
now = start;
ans.push_back(now);
while(now != end)
{
int tmp = 1<<6;
for(int i = pre[now]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
//由于输出字典序最小的,所以求出满足dis[now] - dis[v] == edge[i].w中最小的v
if(dis[now] - dis[v] == edge[i].w && v < tmp)
{
tmp = v;
}
}
ans.push_back(tmp);
now = tmp;
} printf("%c",ans[0]+'A'); for(int i = 1; i < (int)ans.size(); i++)
printf("-%c",ans[i]+'A');
printf("\n");
}
int main()
{
int item = 1;
char t1,t2;
while(~scanf("%d",&m))
{
if(m == -1) break;
init();
getchar();
for(int i = 0; i < m; i++)
{
scanf("%c %c",&t1,&t2);
getchar();
add(t1-'A',t2-'A');
add(t2-'A',t1-'A');
} scanf("%lld %c %c",&p,&t1,&t2);
start = t1-'A';
end = t2-'A'; dijstra();
printf("Case %d:\n",item++);
printf("%lld\n",dis[start]);
solve();
}
return 0;
}
uva 10537 Toll! Revisited(优先队列优化dijstra及变形)的更多相关文章
- UVA 10537 Toll! Revisited (逆推,最短路)
从终点逆推,d[u]表示进入u以后剩下的货物,那么进入u之前的货物数量设为y,d[u] = x,那么y-x=ceil(y/20.0)=(y-1)/20+1=(y+19)/20. (y-x)*20+r= ...
- UVA 10537 - The Toll! Revisited(dijstra扩张)
UVA 10537 - The Toll! Revisited option=com_onlinejudge&Itemid=8&page=show_problem&catego ...
- 地铁 Dijkstra(优先队列优化) 湖南省第12届省赛
传送门:地铁 思路:拆点,最短路:拆点比较复杂,所以对边进行最短路,spfa会tle,所以改用Dijkstra(优先队列优化) 模板 /******************************** ...
- 最短路算法模板合集(Dijkstar,Dijkstar(优先队列优化), 多源最短路Floyd)
再开始前我们先普及一下简单的图论知识 图的保存: 1.邻接矩阵. G[maxn][maxn]; 2.邻接表 邻接表我们有两种方式 (1)vector< Node > G[maxn]; 这个 ...
- UVA10537 Toll! Revisited
difkstra + 路径输出 The Toll! Revisited Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...
- 堆优化dijstra
因为spfa没事就被卡一卡,所以堆优化dijstra就显得很重要,在最短路或者其模型里边,最少有一条边是没有被更新过的,也就是它是最短的,同理从这个点开始也有一条边最短,所以每次就找最短的然后松弛操作 ...
- dijkstra 的优先队列优化
既然要学习算法,就要学习到它的精髓,才能够使用起来得心应手. 我还是远远不够啊. 早就知道,dijkstra 算法可以用优先队列优化,我却一直不知道该怎样优化.当时,我的思路是这样的:假设有n个顶点, ...
- poj 1511 优先队列优化dijkstra *
题意:两遍最短路 链接:点我 注意结果用long long #include<cstdio> #include<iostream> #include<algorithm& ...
- 最短路--dijkstra+优先队列优化模板
不写普通模板了,还是需要优先队列优化的昂 #include<stdio.h> //基本需要的头文件 #include<string.h> #include<queue&g ...
随机推荐
- (LeetCode 160)Intersection of Two Linked Lists
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- linux的子进程调用exec( )系列函数
exec( )函数族 : 以下我们来看看一个进程怎样来启动还有一个程序的运行.在Linux中要使用exec函数族.系统调用execve()对当前进程进行替换,替换者为一个指定的程序,其參数包含文件名称 ...
- 如何使用Total Recorder录制网上的音乐,如何下载只能试听的歌曲
1 在网上找到了对应的网站.其中正在播放的歌曲正是我们想要的 2 在地址栏输入上面音乐网站的网址,并点击捕获广播.(URL直接给出了音乐的完整地址,比如http://www.someserver.co ...
- windows系统上安装Redis,并且设置Redis密码
一.Windows版本的Redis下载 下载地址:https://github.com/MSOpenTech/redis/releases 我下载的是最新版的3.2 二.安装Redis 我下载的是安装 ...
- photoshop 去掉gif水印
先贴上未去除水印的GIF图片!~ 打开选中需要处理的“gif文件” 下面就以动图给大家介绍一下: 首先勾选 时间轴和图层 第二步(选择区域) 第三步(选择水印区域),选择完了以后按Enter 选中第一 ...
- [2014.5.13][Ubuntu] Ubuntu 14.04STL 出现NTFS分区无法訪问的问题
5.12 为了给学生改论文,在UPC上登录了Windows 8.1,晚上正常关机.今日切换登陆Ubuntu 14.04分区,发现原来能够正常訪问的windows下的NTFS分区都被锁死.提演示样例如以 ...
- CSS3 选择器浏览器兼容性汇总 IE8
1.css选择器 css(包括css1.css2和css3)有哪些选择器? http://www.w3school.com.cn/cssref/css_selectors.asp 2.CSS3选择器 ...
- Android:Dialog中隐藏键盘的注意事项
场景:弹出一个Dialog.里面有一个EditText.用来输入内容.由于输入时.须要弹出键盘.所以当Dialog消失时.键盘要一起隐藏. 如今我们做一个自己定义的Dialog MyDialog ex ...
- 解决Eclipse的Servers视图中无法添加Tomcat6/Tomcat7
如何解决 . 关闭Eclipse . 打开WorkSpace所在的位置. {workspace-directory}/.metadata/.plugins/org.eclipse.core.runti ...
- EXCEPTION-SPRING
CreateTime--2016年8月23日09:00:47Author:Marydon 声明:异常类文章主要是记录了我遇到的异常信息及解决方案,解决方案大部分都是百度解决的,(这里只是针对我遇到 ...