洛谷 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;
    }
}

 

 

 

posted @ 2017-09-03 19:47  一蓑烟雨任生平  阅读(423)  评论(0编辑  收藏  举报