loj 1379(最短路变形)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27087

思路:题目的意思是求S->T的所有路径中花费总和小于给定的P值的所经过的路径上的最大权值。我们可以从起点做一次SPFA,然后求出起点到所有点的最短路径,然后以终点为起点,将边反向,求终点到起点的最短路,然后枚举每一条边即可,求最大值。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 #define MAXN 22222
 8 #define MAXM 222222
 9 #define inf 1<<30
10 #define FILL(a,b) memset(a,b,sizeof(a))
11 
12 template<class T>inline T Get_Min(const T &a,const T &b){ return a<b?a:b; }
13 template<class T>inline T Get_Max(const T &a,const T &b){ return a>b?a:b; }
14 struct Edge{
15     int v,w,next;
16 }edge1[MAXM],edge2[MAXM];
17 
18 int n,m,st,ed,p,NE1,NE2;
19 int head1[MAXN],head2[MAXN];
20 
21 void Insert1(int u,int v,int w)
22 {
23     edge1[NE1].v=v;
24     edge1[NE1].w=w;
25     edge1[NE1].next=head1[u];
26     head1[u]=NE1++;
27 }
28 
29 void Insert2(int u,int v,int w)
30 {
31     edge2[NE2].v=v;
32     edge2[NE2].w=w;
33     edge2[NE2].next=head2[u];
34     head2[u]=NE2++;
35 }
36 
37 int dist[2][MAXN];
38 bool mark[MAXN];
39 void spfa(int st,int ed,Edge *edge,int *dist,int *head)
40 {
41     FILL(mark,false);
42     fill(dist,dist+n+2,inf);
43     queue<int>que;
44     que.push(st);
45     dist[st]=0;
46     while(!que.empty()){
47         int u=que.front();
48         que.pop();
49         mark[u]=false;
50         for(int i=head[u];i!=-1;i=edge[i].next){
51             int v=edge[i].v,w=edge[i].w;
52             if(dist[u]+w<dist[v]){
53                 dist[v]=dist[u]+w;
54                 if(!mark[v]){
55                     mark[v]=true;
56                     que.push(v);
57                 }
58             }
59         }
60     }
61 }
62 
63 
64 int main()
65 {
66     int _case,u,v,w,ans,t=1;
67     scanf("%d",&_case);
68     while(_case--){
69         scanf("%d%d%d%d%d",&n,&m,&st,&ed,&p);
70         NE1=NE2=0;
71         FILL(head1,-1);
72         FILL(head2,-1);
73         while(m--){
74             scanf("%d%d%d",&u,&v,&w);
75             Insert1(u,v,w);
76             Insert2(v,u,w);
77         }
78         spfa(st,ed,edge1,dist[0],head1);
79         spfa(ed,st,edge2,dist[1],head2);
80         ans=-1;
81         for(int u=1;u<=n;u++){
82             for(int i=head1[u];i!=-1;i=edge1[i].next){
83                 int v=edge1[i].v,w=edge1[i].w;
84                 if(dist[0][u]!=inf&&dist[1][v]!=inf&&dist[0][u]+w+dist[1][v]<=p){
85                     ans=Get_Max(ans,w);
86                 }
87             }
88         }
89         printf("Case %d: %d\n",t++,ans);
90     }
91     return 0;
92 }
View Code

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值