UVA 10537 The Toll! Revisited uva1027 Toll(最短路+数学坑)
前者之所以叫加强版,就是把uva1027改编了,附加上打印路径罢了。
03年的final题哦!!虽然是水题,但不是我这个只会做图论题的跛子能轻易尝试的——因为有个数学坑。
题意:运送x个货物从a->b,沿途要上交过路费,village(小写字母)只需交一个单位的货物,town(大写字母)要交(x/20+((x%20==0)?0:1))个单位的货物,即每20个货物要上交一个,不足的按20处理。现在已知要送到b点y个货物,那么最少从x出发要携带多少个货物。
注意:
1、路过town:19=20-1,同时19=21-2,所以要求最小值。
2、用dijkstra做,不过是从 b->a ,路径u->v的权值为经过u点扣除的货物。
3、打印路径:反向。从a->b,沿着d[v]==d[u]-s走,必为最短路。(从b->a有多条最短路,但从a->b沿着这个条件走,只有一条最短路)
4、字典序最小:预处理,sort()后再建图。已知邻接表是模仿指针的头插法——后进先出。
5、数学坑= =:
先举个例子,要送到town A 10000个货物,针对10000,要扣除500。那么是不是携带10500就能满足要求呢?不是的T^T,10500-525==9975。所加上的500,仍然会被扣除一些货物。(TLE的原因,本以为差的不多,就每次做++判断了)
用递推直接求每部分要补充的货物,用大数据测发现差了1。这不是计算问题,而是存在错误的:沿用上一个例子,要送10000个货物,需扣除500个,500又需扣25个,那么25需不需要扣呢?扣的话又要扣2个,那么两个还要再扣一个么??关键是余数,两次扣除的余数均不为0,那么分开算要扣2个,然而两数之和不足20,只需扣1个。
所以要直接求。
6、不要忘了long long,__int64 害我CE了一发
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#define LL long long
using namespace std; const int MAXN=;
const LL INF =1e12+; struct Edge{
int v,next;
Edge(){}
Edge(int _v,int _next):v(_v),next(_next){}
}edge[MAXN*MAXN]; struct N{
int l,r;
}a[MAXN*MAXN]; int cmp(N a,N b)
{
if(a.l==b.l)
return a.r>b.r;
return a.l<b.l;
} int head[MAXN],tol;
int vis[MAXN];
LL d[MAXN];
queue<int>q; void init()
{
tol=;
memset(head,-,sizeof(head));
} void add(int u,int v)
{
edge[tol]=Edge(v,head[u]);
head[u]=tol++;
} void dijkstra(int st,int c)
{
memset(vis,,sizeof(vis));
for(int i=;i<;i++)
if(i==st)d[i]=c;
else d[i]=INF;
for(int i=;i<;i++)
{
if(head[i]==-)
continue; int x;
LL m=INF;
for(int j=;j<;j++)
{
if(!vis[j]&&d[j]<m){
x=j;
m=d[x];
}
}
vis[x]=;
LL t=,p=d[x];
if(x<)
while((p+t)-(p+t)/-((p+t)%==?:)<d[x])
{
t+=d[x]-((p+t)-(p+t)/-((p+t)%==?:));
}
else
t=;
for(int j=head[x];j!=-;j=edge[j].next)
{
int v=edge[j].v; if(d[v]>d[x]+t){
d[v]=d[x]+t;
}
}
}
} void road(int st,int ed)
{
int u=st;
LL s;
while(u!=ed)
{
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v;
if(v<)
s=d[u]/+((d[u]%==)?:);
else
s=;
if(d[v]==d[u]-s){
q.push(v);
u=v;
break;
}
}
}
while(!q.empty())
{
int v=q.front();q.pop();
if(v<)
printf("-%c",v+'A');
else
printf("-%c",v-+'a');
}
printf("\n");
} int num(char ch)
{
if('a'<=ch&&ch<='z')
return (+ch-'a');
else
return (ch-'A');
} int main()
{
int n,c,cnt=;
char str1[],str2[];
while(~scanf("%d",&n))
{
if(n==-)
return ;
init();
for(int i=;i<n;i++)
{
scanf("%s%s",str1,str2);
a[i].l=num(str1[]);
a[i].r=num(str2[]);
}
sort(a,a+n,cmp);
for(int i=;i<n;i++)
{
add(a[i].l,a[i].r);
add(a[i].r,a[i].l);
} scanf("%d%s%s",&c,str1,str2);
int x=num(str1[]);
int y=num(str2[]);
dijkstra(y,c); printf("Case %d:\n",cnt++);
printf("%lld\n",d[x]);
if(x<)
printf("%c",x+'A');
else
printf("%c",x-+'a');
road(x,y);
}
return ;
}
a b
b c
a d
d c
a c A B
B C
C D
D E
E F
F G
G H
H I
I J
J K
K L
L M
M N
N O
O P
P Q
Q R
R S
S T
T U
U V
V W
W X
X Y
Y Z
Z a
a b
b c
c d
d e
e f
f g
g h
h i
i j
j k
k l
l m
m n
n o
o p
p q
q r
r s
s t
t u
u v
v w
w x
x y
y z
A z A b
A B
b c
B c
A c A b
A B
b c
B c
A c A D
D X
A b
b c
c X
A X -
input
Case : a-b-c Case : A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z-a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z Case : A-B-c Case : A-b-c Case : A-b-c-X
output
唉,吐槽一下。谁调试不用数据,就不能共享一下?做图论整天挨卡,想找个数据都找不到,自己又造不出好数据,要不然昨天那道lca就不会枚举344组数据了。当然,偶也知道debug的能力是重中之重,但这是经验积累起来的,以我这种弱菜,去刷uva&LA这种连题解都找不到的题库,受老咔哒了。难怪队友都说我整天愁眉苦脸的= =
UVA 10537 The Toll! Revisited uva1027 Toll(最短路+数学坑)的更多相关文章
- UVA 10537 The Toll! Revisited 过路费(最短路,经典变形)
题意:给一个无向图,要从起点s运送一批货物到达终点e,每个点代表城镇/乡村,经过城镇需要留下(num+19)/20的货物,而经过乡村只需要1货物即可.现在如果要让p货物到达e,那么从起点出发最少要准备 ...
- UVA 10537 - The Toll! Revisited(dijstra扩张)
UVA 10537 - The Toll! Revisited option=com_onlinejudge&Itemid=8&page=show_problem&catego ...
- uva 10537 Toll! Revisited(优先队列优化dijstra及变形)
Toll! Revisited 大致题意:有两种节点,一种是大写字母,一种是小写字母. 首先输入m条边.当经过小写字母时须要付一单位的过路费.当经过大写字母时,要付当前財务的1/20做过路费. 问在起 ...
- UVA10537 Toll! Revisited
difkstra + 路径输出 The Toll! Revisited Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...
- UVA 816 -- Abbott's Revenge(BFS求最短路)
UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...
- 【Toll!Revisited(uva 10537)】
题目来源:蓝皮书P331 ·这道题使得我们更加深刻的去理解Dijkstra! 在做惯了if(dis[u]+w<dis[v])的普通最短路后,这道选择路径方案不是简单的比大小的题横在了 ...
- UVa 10537 The Toll! Revisited (最短路)
题意:给定一个图,你要从 s 到达 t,当经过大写字母时,要交 ceil(x /20)的税,如果经过小写字母,那么交 1的税,问你到达 t 后还剩下 c 的,那么最少要带多少,并输出一个解,如果多个解 ...
- The Toll! Revisited UVA - 10537(变形。。)
给定图G=(V,E)G=(V,E),VV中有两类点,一类点(AA类)在进入时要缴纳1的费用,另一类点(BB类)在进入时要缴纳当前携带金额的1/20(不足20的部分按20算) 已知起点为SS,终点为TT ...
- 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= ...
随机推荐
- c++ std::bitset
转载自 作用:及 64位 移位 取或 用64个位存储64个位,取 或 merge . 然后查索引即知道id是否存在~~ 目标:省空间. #include <iostream> #in ...
- hihocoder #1300 : 展胜地的鲤鱼旗 dp
题目链接: http://hihocoder.com/problemset/problem/1300 题解: 先用栈预处理出每个‘)’匹配的‘(’的位子,放在pos数组中. dp[i]表示以i结尾的合 ...
- 16进制串hex与ASCII字符串相互转换
提供两个函数,方便十六进制串与ASCII 字符串之间的相互转换,使用函数需要注意的是返回的串是在堆上通过 calloc 分配的,所以,记得使用完返回值释放该块,并且将指向该块的指针 =NULL . c ...
- win8 任务栏不合并隐藏标题
让win8任务栏不合并,并且隐藏标题的办法: 效果如下: 首先让win8不合并任务栏 1.任务栏上点鼠标右键 -- "属性" 2."任务栏按钮"选择" ...
- spoj 274
离散化 枚举行 扫描横坐标 #include <iostream> #include <cstdio> #include <cstring> #include ...
- 表中相同数据的sql语句
1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select * from peoplewhere peopleId in (select peopleId from ...
- pl/sql tutorial
http://plsql-tutorial.com/plsql-procedures.htm What is PL/SQL? PL/SQL stands for Procedural Language ...
- POJ 4044 Score Sequence
题目链接 题意 :给你两个序列,进行降序排序,找出连续的公共子序列,将这个子序列输出,然后对个位数升序排序,如果个位数相同就按数的大小排,再输出这个新排好的. 思路 :先排序,再找公共子序列,最后个位 ...
- python logging 学习笔记
logging.basicConfig函数各参数: filename: 指定日志文件名 filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a' format: 指定输出的格 ...
- Android:Android SDK Manager顺利下载
默认的Android SDK只有Android 4.4的版本,如果需要其他版本的模拟器,需要Android SDK Manager下载, 1.打开Eclipse 2.选择Android SDK Man ...