[题解]I - Slow Leak (dij)(floyd) Kattis - slowleak

I - Slow Leak

You are an avid cyclist and bike every day between your home and school. Usually, your ride is uneventful and you bike along the shortest path between home and school. After school this afternoon you realized you have a slow leak in your bike tire—the tire can hold some air, but not for long. Refilling the tire allows you to ride your bike for some distance, after which your tire goes flat again and it becomes impossible to ride any further (and you refuse to walk your bicycle).

Luckily for you, your city has installed several bike repair stations at intersections throughout town where you can refill your tire and bike again until the tire goes flat. There’s a repair station at your school too, so that you can fill up your tire before you start on your trip home.

You’ve calculated how far you can bike before your tire runs out of air and you know the layout of your town, including all the intersections, distances between them, and the locations of the repair stations. What is the shortest possible trip from school to your home that you can take without becoming stuck due to a flat tire? (You do not become stuck if you roll into a repair station, or your home, at the exact same time as your tire goes flat.)

\includegraphics[width=0.7\textwidth ]{samples.pdf}
Figure 1: An illustration of the two sample inputs.
Input

The first line of input contains four integers nn, mm, tt, and dd, satisfying 2≤n≤5002≤n≤500, 0<m≤n(n−1)/20<m≤n(n−1)/2, 0<t<n0<t<n and 0<d<2310<d<231. The value nn represents the number of intersections in the city, mm represents the number of roads in the city, tt is the number of repair stations and dd is the distance that you can bike (starting with a fully inflated tire) before your tire goes flat again. The intersections are numbered from 11 to nn. Your school is at intersection 11 and your home is at intersection nn.

The second line of input contains tt integers, with values between 22 and n−1n−1, inclusive. These are the intersections where the repair stations are located (excluding your school’s repair station). All integers on this line are unique.

The next mm lines represent the roads in your town. Each has three integers i,j,ki,j,k, where 1≤i<j≤n1≤i<j≤n, and 0<k<2310<k<231. These three integers represent that there is a direct road from intersection ii to intersection jj of length kk. Roads can be traveled in either direction. There is at most one road between any two intersections.

Output

Print the minimum total distance you need to travel to reach home from school without getting stuck due to a flat tire. If the trip is not possible, output the word stuck on a single line instead.

It is guaranteed that if the trip is possible, the minimum distance DD satisfies 0<D<2310<D<231.

Sample Explanation

In the first sample input, if your tire did not have a leak then the shortest path home would have a distance of 99, going from the school through intersections 33 and 55. However, due to the leak, you can only travel a distance of 44 before you need to refill the tire, requiring you to use the repair stations at intersections 22 and 55, for a total distance of 1212.

In the second sample input, if your tire did not have a leak, then the shortest path home would have a distance of 1212. But since your tire only lasts for a distance of 1010, there’s no path where your bike tire will not go flat somewhere along the way. Even when using repair station at intersection 22, you get stuck before you can reach either your home or the repair station at intersection 55.

Sample Input 1
6 7 2 4
2 5
1 2 4
1 3 5
2 3 3
3 4 2
3 5 1
4 6 4
5 6 4
Sample Output 1
12
Sample Input 2
6 7 2 10
2 5
1 2 1
1 3 2
2 3 1
3 4 8
4 5 3
4 6 2
5 6 1
Sample Output 2
stuck
题意:给你一张图,再给你几个标记的点,每次移动只能在标记的点以及起点终点间进行,求是否能够达到终点,并输出最短距离。
思路:理解了这个题的题意之后,思路也很好想,首先他给了一个N的范围是<500 我们可以用floyd先跑一遍,得到任一点到任意点的最短路,接着我们构造一张图,该图是只包含标记点及其终点,起点的一张图,两点的距离已由我们floyd求得;在得到的新图上进行dijkstra算法,求一条由起点到终点的最短路径。
ans:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#define ll long long
#define pb push_back
using namespace std;
const ll inf=1e10;
ll n,m,t,d,g[598][598],dis[588];bool vis[599];
vector<ll>G[598],x;
vector<ll>value[598];
void floyd(){
    for(ll k=1;k<=n;++k)
        for(ll i=1;i<=n;++i)
            for(ll j=1;j<=n;++j)
                g[i][j] = min(g[i][j],g[i][k]+g[k][j]);
}
void visd(){
    ll len = (ll)x.size();
    for(ll i=0;i<len;++i){
        if(g[1][x[i]]<=d){
            G[1].pb(x[i]);G[x[i]].pb(1);
            value[1].pb(g[1][x[i]]);value[x[i]].pb(g[1][x[i]]);
        }
        if(g[n][x[i]]<=d){
            G[n].pb(x[i]);G[x[i]].pb(n);
            value[n].pb(g[n][x[i]]);value[x[i]].pb(g[n][x[i]]);
        }
        for(ll j=i+1;j<len;++j){
            ll p = x[i],q = x[j];
            if(g[p][q]<=d){
                G[p].pb(q);G[q].pb(p);
                value[q].pb(g[p][q]);
                value[p].pb(g[p][q]);
            }
        }
    }
}
struct cmp{
    bool operator () (ll a,ll b){
        return dis[a]>dis[b];
    }
};
priority_queue<ll ,vector<ll>,cmp>q;
void dij(){
    for(ll i=1;i<=n;++i)dis[i] = inf;
    dis[1] = 0;
    q.push(1);
    while(!q.empty()){
        ll id = q.top();
        q.pop();
        if(vis[id])continue;
        vis[id] = 1;
        ll len = (ll)G[id].size();
        for(ll i=0;i<len;++i){
            ll p = G[id][i];
            if(dis[p]>dis[id]+value[id][i]){
                dis[p]=dis[id]+value[id][i];
                //printf("%d %d\n",p,dis[p]);
                if(!vis[p])q.push(p);
            }
        }
    }
}
void solve(){
    scanf("%lld%lld%lld%lld",&n,&m,&t,&d);
    for(ll i=1;i<=t;++i){
        ll u;scanf("%lld",&u);x.pb(u);
    }
    for(ll i=1;i<=n;++i)
        for(ll j=1;j<=n;++j)
            if(i==j)g[i][j] = 0;
            else g[i][j] = inf;
    for(ll i=1;i<=m;++i){
        ll u,v,p;
        scanf("%lld%lld%lld",&u,&v,&p);
        g[v][u] = g[u][v] = p;
    }
    floyd();
    if(g[1][n]<=d){printf("%lld\n",g[1][n]);return;}
    visd();
    dij();
    if(dis[n]==inf)puts("stuck");
    else
    printf("%lld\n",dis[n]);
}
int main()
{
    solve();
    return 0;
}

本题还是由很多需要注意的细节的,数据范围是D<2^31那么我们inf取0x3f3f3f3f显然是错的,第一遍交的时候也是因为这个错了一发,我索性将inf改为1e10 ,全开long long 终于跑到了第11组数据,发现若一步能够到达n,答案便是floyd算的g[1][n]的值,加了一个判定条件后果断accepted 这道题有点像昨日补的pta上的题目。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值