标签:site open ems 忽略 printf turn from 代码 putchar
一道最短路的变形题。
不难发现,如果有一条边 \((x,y)\) ,那么如果 \(x\) 物品比较小,\(y\) 的物品就会比较小,无论 \(x,y\) 是城镇还是村庄。
题目给了我们终点的物品数量,这提示我们倒序最短路。
如果我们正着做最短路,那么每一条路的边权都是不确定的。
但如果我们倒着做最短路,不难发现,对于一个村庄,这个权值是 \(1\) ,对于一个城镇,权值是 \(\frac 1{19}d_k\) ,这样每一条边的权值都是确定的,我们就可用最短路来做这个题。
代码:
#include<bits/stdc++.h>
#define dd double
#define ld long double
#define ll long long
#define uint unsigned int
#define ull unsigned long long
#define N 200
#define M 400000
using namespace std;
const int INF=0x3f3f3f3f;
template<typename T> inline void read(T &x) {
x=0; int f=1;
char c=getchar();
for(;!isdigit(c);c=getchar()) if(c == ‘-‘) f=-f;
for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
x*=f;
}
struct edge{
int to,next;ll w;
inline void intt(int to_,int ne_){
to=to_;next=ne_;
}
};
edge li[M];
int head[N],tail=1;
inline void add(int from,int to){
li[++tail].intt(to,head[from]);
head[from]=tail;
}
ll n,d[N],s,t;
struct node{
ll val,id;
inline node(){}
inline node(ll val,ll id) : val(val),id(id) {}
inline bool operator < (const node &b) const{
return val>b.val;
}
};
bool vis[N];
priority_queue<node> q;
inline void dij(int s,ll val){
memset(d,INF,sizeof(d));
q.push(node(val,s));d[s]=val;
while(q.size()){
node top=q.top();q.pop();
if(vis[top.id]) continue;
vis[top.id]=1;
for(int x=head[top.id];x;x=li[x].next){
int to=li[x].to;
ll w=(top.id<=90)?ceil((dd)d[top.id]/19.0):1;
if(vis[to]||d[to]<=d[top.id]+w) continue;
d[to]=d[top.id]+w;li[x].w=w;li[x^1].w=w;
q.push(node(d[to],to));
}
}
}
inline char get_char(){
char c=getchar();
while((c<‘a‘||c>‘z‘)&&(c<‘A‘||c>‘Z‘)) c=getchar();
return c;
}
inline void print(int k){
if(k!=s) putchar(‘-‘);
printf("%c",(char)k);
for(int x=head[k];x;x=li[x].next){
int to=li[x].to,w=li[x].w;
if(d[to]+w==d[k]){
print(to);
return;
}
}
}
inline void clear(){
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
memset(li,0,sizeof(li));
tail=1;
}
int tot;
int main(){
// freopen("my.in","r",stdin);
// freopen("my.out","w",stdout);
while(scanf("%lld",&n)){
clear();
tot++;if(tot!=1) putchar(‘\n‘);
if(n==-1) break;
for(int i=1;i<=n;i++){
char from,to;from=get_char();to=get_char();
add((int)from,(int)to);add((int)to,(int)from);
}
ll num;char sc,tc;
scanf("%lld",&num);sc=get_char();tc=get_char();
s=(int)sc;t=(int)tc;
dij(t,num);
printf("Case %d:\n%lld\n",tot,d[s]);
print(s);
}
return 0;
}
顺着当前线索先想一想看看有没有什么途径解决以前的问题,或者首先忽略一些限制的影响。
题解 UVA10537 The Toll! Revisited 最短路
标签:site open ems 忽略 printf turn from 代码 putchar
原文地址:https://www.cnblogs.com/TianMeng-hyl/p/14964297.html