洛谷 U6254 最低费用
题目背景
小明暑假去国外游玩,到了最后一天,却发现自己的钱还不一定够去机场,于是他开始对国外特殊的交通方式进行研究,但是他发现路段的错综复杂使他头脑昏花,于是他打开电脑,希望你去帮助他(不求上进的小明)。
题目描述
小明有m元,他去机场必须使用一种国外特有的交通方式,是这样的:
有n个站点,k种车,每个站点都可以到达特定的一些站点,所用的费用自然也是不同的,每个站点都有着足够的车,可以让你随到随走。现在知道小明在x站点,他要去y站点,以及每个站点到达某些站点的费用(一个站点不是其他站点都可以到),请问以小明手上的钱,能不能到达y站点。
以上在现实中纯属瞎扯[根本没有这种这种方法]
输入输出格式
输入格式:
共k+2行,第一行是三个整数n,m,k,含义如题,第二行是x和y,代表小明所在的站点和目标站点,然后的k行每行都有三个数,a,b,c,代表从a站点到b站点需要花费c元。
输出格式:
两行,如果小明的钱够从x站点到y站点就输出“Yes”,下一行是小明剩余的钱数。
如果x站点无法到达y站点或小明的钱不够去y站点就输出“No”,下一行是以小明现在的钱数能到达的离y站点最近的一个站点。
输入输出样例
输入样例#1:
10 20 18
1 10
1 2 2
1 3 5
1 4 1
2 5 12
2 6 14
3 5 6
3 6 10
3 7 4
4 5 13
4 6 12
4 7 11
5 8 3
5 9 9
6 8 6
6 9 5
7 9 10
8 10 5
9 10 2
输出样例#1:
Yes
1
输入样例#2:
5 5 2
1 3
1 4 5
1 2 5
输出样例#2:
No
2
说明
- 数据说明
2<=n<=30
1<=k<=50
10<=m<=32767
1<=单次费用<=100
1<=x<y<=n
1<=a<b<=n
- 样例1说明 从1到3 ans=5
从3到5 ans=11
从5到8 ans=14
从8到10 ans=19
- 样例2说明
1无法到3
只能到2或4,根据以下注备,输出No'/n'2。
/n=换行符。
- 注备
如果小明哪都去不了就输出“No”和他所在的站点
如果y=3,小明无法到达3站点,但是却可以到达2和4站点,优先输出2。
a<b,说明序号低的站点可以到达序号高的站点,反之不行
思路:spfa
#include<iostream> #include<queue> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 60 using namespace std; queue<int>que; int n,m,k,s,t,tot; int dis[MAXN],vis[MAXN],ans,maxn=0x7f7f7f7f; int to[MAXN],head[MAXN],net[MAXN],cap[MAXN]; void add(int u,int v,int w){ to[++tot]=v; net[tot]=head[u]; cap[tot]=w; head[u]=tot; } void spfa(int x){ memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); while(!que.empty()) que.pop(); que.push(x); dis[x]=0;vis[x]=1; while(!que.empty()){ int now=que.front(); que.pop(); vis[now]=0; for(int i=head[now];i;i=net[i]) if(dis[to[i]]>dis[now]+cap[i]){ dis[to[i]]=dis[now]+cap[i]; if(!vis[to[i]]){ vis[to[i]]=1; que.push(to[i]); } } } } int main(){ scanf("%d%d%d",&n,&m,&k); scanf("%d%d",&s,&t); for(int i=1;i<=k;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); } spfa(s); if(dis[t]<=m){ cout<<"Yes"<<endl<<m-dis[t]; return 0; } else{ cout<<"No"<<endl; for(int i=1;i<=n;i++) if(dis[i]<=m) if(abs(i-t)<maxn){ ans=i; maxn=abs(i-t); } cout<<ans; } }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。