题目链接
题意:给定一个无向图,大写字母是城市,小写字母是村庄,经过城市交过路费为当前货物的%5,路过村庄固定交1,给定起点终点和到目标地点要剩下的货物,问最少要带多少货物上路,并输出路径,如果有多种方案,要求字典序最小
solution:反向建图, d[i]表示从i到终点需要的数量。
#include <map>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = ;
const long long Inf = (L<<);
struct Edge{
int u, v, w;
Edge(int u, int v, int w):u(u),v(v),w(w){}
};
struct HeapNode{
long long d;int u;
bool operator<(const HeapNode& rhs) const{
return d>rhs.d;
}
};
char to[];
struct Dijkstra{
int n, m;
long long d[N];
bool done[N];
vector<Edge> edges;
vector<int> G[N];
int p[N];
void init(int n){
this->n=n;
for ( int i=; i<n; i++ ) G[i].clear();
edges.clear();
}
void addeage(int u, int v, int w){
edges.push_back((Edge){u,v,w});
m=edges.size();
G[u].push_back(m-);
}
void print(int u){
if( p[u]==- ){
printf("%c\n", to[u]);
return;
}
printf("%c-", to[u] );
print(edges[p[u]].u);
}
void dijkstra(int s, long long vl){
for ( int i=; i<n; i++ ) d[i]=Inf, done[i]=;
d[s]=vl;
p[s]=-;
priority_queue<HeapNode> Q;
Q.push((HeapNode){vl,s});
while( !Q.empty() ){
HeapNode x=Q.top(); Q.pop();
int u=x.u;
if( done[u] ) continue;
done[u]=;
for ( int i=; i<G[u].size(); i++ ){
Edge& e=edges[G[u][i]];
long long nd;
if( e.w ) nd= (long long) ceil(d[u]*/*);
else nd=d[u]+;
if( d[e.v]>nd || d[e.v]==nd && to[u]<to[edges[p[e.v]].u] ){
d[e.v]=nd;
p[e.v]=G[u][i];
Q.push((HeapNode){d[e.v],e.v});
}
}
}
}
};
struct SPFA{
int n, m;
long long d[N];
bool inq[N];
int p[N];
vector<Edge> edges;
vector<int> G[N];
void init(int n){
this->n=n;
for ( int i=; i<n; i++ ) G[i].clear();
edges.clear();
}
void addeage(int u, int v, int w){
edges.push_back((Edge){u,v,w});
m=edges.size();
G[u].push_back(m-);
}
void print(int u){
if( p[u]==- ){
printf("%c\n", to[u] );
return ;
}
printf("%c-", to[u] );
print(edges[p[u]].u);
}
void spfa(int s, long long vl){
for ( int i=; i<n; i++ ) d[i]=Inf, inq[i]=;
d[s]=vl;
p[s]=-;
queue<int> Q;
Q.push(s);
while( !Q.empty() ){
int u=Q.front(); Q.pop();
inq[u]=;
for ( int i=; i<G[u].size(); i++ ){
Edge& e=edges[G[u][i]];
long long nd;
if( e.w ) nd=(long long) ceil(d[u]*/*);
else nd=d[u]+;
if( d[e.v]>nd || d[e.v]==nd && to[u]<to[edges[p[e.v]].u] ){
d[e.v]=nd;
p[e.v]=G[u][i];
if( !inq[e.v] ){
inq[e.v]=;
Q.push(e.v);
}
}
}
}
}
};
SPFA D;
int vis[];
int main(){
for ( int i=; i<; i++ ) {
vis['a'+i]=i+; to[i+]='a'+i;
vis['A'+i]=i; to[i]='A'+i;
}
int n, m, kas=;
while( scanf("%d", &m ) == && m!=- ){
D.init();
char a[], b[];
for ( int i=; i<=m; i++ ){
scanf("%s%s", a, b );
int u=vis[a[]], v=vis[b[]];
D.addeage(u,v,a[]<'a');
D.addeage(v,u,b[]<'a');
}
long long vl;
scanf("%lld%s%s", &vl, a, b );
int u=vis[a[]], v=vis[b[]];
D.spfa(v,vl);
printf("Case %d:\n", ++kas);
printf("%lld\n", D.d[u]);
D.print(u);
}
}