analysis
如果可以求出一个数组d[i]表示从i到达终点所需要的最少金额的话,这道题就解决了呗
但是如何求出这个数组呢?
可以用dijkstra来反推,把终点的距离设为最后一行的数字(也就是需要运到终点的货物量),然后对整个图以合适的松弛操作反着跑一个dij,然后就求出了这个数组
于是现在最关键的问题就是如何松弛:
对于边u到v,由于我们是反向跑的,因此如果u是一个城市,那么v走到u必然就要
1
20
\frac{1}{20}
201的税,如果是一个村庄那么就只交1单位的税,那么在松弛的时候只需要根据u的类别分类讨论即可
code
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;+--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
template<typename T>void read(T &x){
x=0;char r=getchar();T neg=1;
while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
x*=neg;
}
int n;
const int maxn=100005;
const int maxm=500005;
const long long INF=1e18;
struct node{
int e;
int nxt;
}edge[maxm];
int head[maxn];
int cnt=0;
inline void addl(int u,int v){
edge[cnt].e=v;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
int S,E;
ll dis[maxn];
struct point{
int pos;
ll dis;
point():pos(0),dis(0){}
point(int pos,ll dis):pos(pos),dis(dis){}
friend bool operator<(point a,point b){
return a.dis>b.dis;
}
};
bool in[maxn];
priority_queue<point>q;
inline ll getdis(int u,int v){
if(u>='a'-'A')
return 1;
else return (long long)ceil(dis[u]/19.0);
}
int pre[maxn];
void dijkstra(){
clean(in,false);
q.push(point(E,dis[E]));
while(q.empty()==false){
int f=q.top().pos;
q.pop();
if(in[f])
continue;
in[f]=true;
for(int i=head[f];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if((dis[v]>dis[f]+getdis(f,v))||(dis[v]==dis[f]+getdis(f,v)&&pre[v]>f)){
dis[v]=dis[f]+getdis(f,v);
pre[v]=f;
q.push(point(v,dis[v]));
}
}
}
}
void getans(int u){
if(u==E){
printf("%c\n",E+'A');
return;
}
printf("%c-",u+'A');
getans(pre[u]);
}
int main(){
int NFG=0;
while(1){
read(n);
if(n==-1)
break;
printf("Case %d:\n",++NFG);
clean(head,-1);
cnt=0;
loop(i,1,n){
char P[10],S,E;
scanf("%s",P);
S=P[0];
getchar();
scanf("%s",P);
E=P[0];
addl(S-'A',E-'A');
addl(E-'A',S-'A');
}
clean(dis,0x3f);
int disn;
char P[10];
read(disn);
scanf("%s",P);
S=P[0]-'A';
getchar();
scanf("%s",P);
E=P[0]-'A';
dis[E]=disn;
dijkstra();
printf("%lld\n",dis[S]);
getans(S);
}
return 0;
}