1 条题解
-
0
自动搬运
来自洛谷,原作者为

Soul_Love
这个家伙很懒,什么都留下了搬运于
2025-08-24 22:38:38,当前版本为作者最后更新于2022-06-24 17:54:00,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目大意
我觉得这道题最大的难点就是题目的意思,在此我简单说明一下。一开始,商人就有 1kg 黄金(也就是说没有费用)。接着就是转化,这是在过边境前后都可以进行的。还有就是在过边境之后经过若干次转化后,商人手上拿着的必须是黄金。
是不是感觉换了道题???思路
我用的是 Dijkstra,这很好想。为了解决过边境的问题,对于每种金属都建两个点,分别是过边境前的和过边境后的。对于转化,直接连两种所给的金属。对于交税,直接把两个同金属过边境前和过边境后的点连边,费用为该金属的单价的一半。最后套模板就可以了。
代码
#include<bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f using namespace std; int n,m,s=1,h[500100],dis[500100],l,vis[500100],x,y,z,t; struct node { int dis,pos; bool operator <(const node &x)const { return x.dis<dis; } }; inline int read() { int k=0,f=0;char c=getchar(); for(;!isdigit(c);c=getchar()) f|=c=='-'; for(;isdigit(c);c=getchar()) k=(k<<1)+(k<<3)+(c^48); return f?-k:k; } priority_queue<node> q; struct edge { int v,next,w; }e[500100]; inline void add(int x,int y,int z) { e[++l].v=y; e[l].w=z; e[l].next=h[x]; h[x]=l; } inline void d()//模板 { for(int i=1;i<=t;i++) dis[i]=inf; dis[s]=0; q.push((node){0,s}); while(!q.empty()) { node t=q.top(); q.pop(); int k=t.pos; if(vis[k]) continue; vis[k]=1; for(int i=h[k];i;i=e[i].next) { if(dis[e[i].v]>dis[k]+e[i].w) { dis[e[i].v]=dis[k]+e[i].w; if(!vis[e[i].v]) q.push((node){dis[e[i].v],e[i].v}); } } } } int main() { n=read(); t=2*n; for(int i=1;i<=n;i++) add(i,i+n,read()*0.5);//依法纳税 m=read(); for(int i=1;i<=m;i++) { x=read(),y=read(),z=read(); add(x,y,z);//过边境前的转化 add(x+n,y+n,z);//过边境后的转化 } d(); printf("%d",dis[n+1]); return 0; }
- 1
信息
- ID
- 7741
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者