light oj 1379 - Toll Management(两次最短路)

23 篇文章 0 订阅

1379 - Toll Management
Time Limit: 2 second(s)Memory Limit: 32 MB

In Dhaka there are too many vehicles. So, the result is well known, yes, traffic jam. So, mostly people have to spend quite a time in the roads to go from one place to another.

Now, the students have finally found a solution to this problem. The idea is to make all the roads one way. That means a vehicle can go through the roads in one way only. And to make the number of vehicles low, each vehicle has to pay a toll to use a road. Now you want to go from a place s to another place t. And you have a total of p taka in your pocket. Now you want to find the path which contains the highest toll road, to go from s to t. Remember that you can't use more than ptaka.

For the given picture, s = 1, t = 5 and p = 10. There are three paths from 1 to 5.

1.      Path 1: 1 - 2 - 5, total toll = 11 (> p)

2.      Path 2: 1 - 3 - 5, total toll = 9 (≤ p), 6 is the maximum toll

3.      Path 3: 1 - 4 - 5, total toll = 9 (≤ p), 5 is the maximum toll

So the maximum toll for a road of all of the paths having total toll not greater than p is 6.

Input

Input starts with an integer T (≤ 10), denoting the number of test cases.

Each case starts with five integers N (2 ≤ N ≤ 10000), M (1 ≤ M ≤ 50000), s (1 ≤ s ≤ N), t (1 ≤ t ≤ N) and p (1 ≤ p ≤ 106) where N means the number of junctions and M means the number of roads connecting the junctions. Then there will be M lines each containing three integers u v cu and v are junctions and there is a road from u to v (1 ≤ u, v ≤ N, u ≠ v) and c (0 ≤ c ≤ 105) is the toll needed for that road. There can be multiple roads between two junctions.

Output

For each case, print the case number and the desired result. If no such result is found, print "-1".

Sample Input

Output for Sample Input

2

5 6 1 5 10

1 2 7

2 5 4

1 3 6

3 5 3

1 4 5

4 5 4

2 1 1 2 10

1 2 20

Case 1: 6

Case 2: -1

Note

Dataset is huge, use faster I/O methods.





题意:n个点m条边,求s到t长度不超过p的最短路中最长边的最小值。

思路:分别从源和汇做两次Dij,最后判断一下求最大值。

代码:

#include <iostream>
#include <functional>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;

#define INF 0x3f3f3f3f
#define mod 1000000009
const int MAXN = 10005;
const int MAXM = 200010;
const int N = 1005;
typedef pair<int,int>pil;

struct Edge
{
    int u,v,w,next;
}edge[MAXM],e[MAXM];

int n,m,s,t,p;
int head[MAXN],hed[MAXN],num1,num2;
int dis1[MAXN],dis2[MAXN];

void init()
{
    num1=0,num2=0;
    memset(head,-1,sizeof(head));
    memset(hed,-1,sizeof(hed));
}

void addedge(int u,int v,int w)
{
    edge[num1].u=u;
    edge[num1].v=v;
    edge[num1].w=w;
    edge[num1].next=head[u];
    head[u]=num1++;
}

void add(int u,int v,int w)
{
    e[num2].u=u;
    e[num2].v=v;
    e[num2].w=w;
    e[num2].next=hed[u];
    hed[u]=num2++;
}

void Dijkstra(int s,int *head,int *dis,Edge *edge)
{
    priority_queue<pil,vector<pil>,greater<pil> >Q;
    dis[s]=0;
    Q.push(make_pair(0,s));
    while (!Q.empty())
    {
        pil st=Q.top();
        Q.pop();
        if (dis[st.second]<st.first) continue;
        for (int i=head[st.second];~i;i=edge[i].next)
        {
            int v=edge[i].v;
            if (dis[v]>dis[st.second]+edge[i].w)
            {
                dis[v]=dis[st.second]+edge[i].w;
                Q.push(make_pair(dis[v],v));
            }
        }
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
    int i,j,c,u,v,w,cas=0;
    scanf("%d",&c);
    while (c--)
    {
        scanf("%d%d%d%d%d",&n,&m,&s,&t,&p);
        init();
        for (i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            add(v,u,w);
        }
        memset(dis1,INF,sizeof(dis1));
        memset(dis2,INF,sizeof(dis2));
        Dijkstra(s,head,dis1,edge);
        Dijkstra(t,hed,dis2,e);
        int ans=-1;
        for (i=0;i<m;i++)
        {
            u=edge[i].u;
            v=edge[i].v;
            if (dis1[u]+dis2[v]+edge[i].w<=p)
                ans=max(ans,edge[i].w);
        }
        printf("Case %d: %d\n",++cas,ans);
    }
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值