90分 蓝桥杯 算法提高 道路和航路 [ 最短路 ]

本文探讨了农夫约翰如何利用最优路径算法将牛奶配送到不同城镇的问题。面对正负权值的边,采用Bellman-Ford算法寻找配送中心到各城镇的最低成本路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

  算法提高 道路和航路  
时间限制:1.0s   内存限制:256.0MB
   
锦囊1
 
锦囊2
 
锦囊3
 
问题描述

农夫约翰正在针对一个新区域的牛奶配送合同进行研究。他打算分发牛奶到T个城镇(标号为1..T),这些城镇通过R条标号为(1..R)的道路和P条标号为(1..P)的航路相连。

每一条公路i或者航路i表示成连接城镇Ai(1<=A_i<=T)和Bi(1<=Bi<=T)代价为Ci。每一条公路,Ci的范围为0<=Ci<=10,000;由于奇怪的运营策略,每一条航路的Ci可能为负的,也就是-10,000<=Ci<=10,000。

每一条公路都是双向的,正向和反向的花费是一样的,都是非负的。

每一条航路都根据输入的Ai和Bi进行从Ai->Bi的单向通行。实际上,如果现在有一条航路是从Ai到Bi的话,那么意味着肯定没有通行方案从Bi回到Ai

农夫约翰想把他那优良的牛奶从配送中心送到各个城镇,当然希望代价越小越好,你可以帮助他嘛?配送中心位于城镇S中(1<=S<=T)。

输入格式

输入的第一行包含四个用空格隔开的整数T,R,P,S。

接下来R行,描述公路信息,每行包含三个整数,分别表示Ai,Bi和Ci

接下来P行,描述航路信息,每行包含三个整数,分别表示Ai,Bi和Ci

输出格式
输出T行,分别表示从城镇S到每个城市的最小花费,如果到不了的话输出NO PATH。
样例输入
6 3 3 4 1 2 5 3 4 5 5 6 10 3 5 -100 4 6 -100 1 3 -10
样例输出
NO PATH NO PATH 5 0 -95 -100
数据规模与约定

对于20%的数据,T<=100,R<=500,P<=500;

对于30%的数据,R<=1000,R<=10000,P<=3000;

对于100%的数据,1<=T<=25000,1<=R<=50000,1<=P<=50000。

 

521961609738062@qq.com道路和航路04-09 10:531.248KBC++运行超时90运行超时5.187MB评测详情

 

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cstring>
 6 #include <vector>
 7 #include <queue>
 8 using namespace std;
 9 
10 #define ll long long
11 
12 const int N = 25005;
13 const ll inf = 0x3f3f3f3f;
14 int n,r,p,s;
15 ll v[N];
16 typedef struct
17 {
18     ll cost;
19     int to;
20 }PP;
21 
22 vector<PP> G[N];
23 int vis[N];
24 
25 void bellman()
26 {
27     memset(vis,0,sizeof(vis));
28     fill(v,v+1+n,inf);
29     v[s]=0;
30     queue<int> que;
31     que.push(s);
32     vis[s]=1;
33     int i;
34     int to;
35     ll cost;
36     while(que.size()>=1)
37     {
38         int te=que.front();
39         que.pop();
40         for(i=0;i<G[te].size();i++){
41             to=G[te][i].to;
42             cost=G[te][i].cost;
43             if(v[to]>v[te]+cost){        
44                 v[to]=v[te]+cost;
45                 if(vis[to]==0){
46                     vis[to]=1;
47                     que.push(to);
48                 }    
49             }
50         }
51         vis[te]=0;
52     }
53 }
54 
55 int main()
56 {
57     int i;
58     //freopen("data.in","r",stdin);
59     scanf("%d%d%d%d",&n,&r,&p,&s);
60     for(i=0;i<=n;i++){
61         G[i].clear();
62     }
63     PP te;
64     int uu,vv;
65     ll cost;
66     for(i=1;i<=r;i++){
67         scanf("%d%d%I64d",&uu,&vv,&cost);
68         te.cost=cost;
69         te.to=vv;
70         G[uu].push_back(te);
71         te.to=uu;
72         G[vv].push_back(te);
73     }
74     for(i=1;i<=p;i++){
75         scanf("%d%d%I64d",&uu,&vv,&cost);
76         te.cost=cost;
77         te.to=vv;
78         G[uu].push_back(te);
79     }
80     bellman();
81     for(i=1;i<=n;i++){
82         if(v[i]==inf){
83             printf("NO PATH\n");
84         }
85         else{
86             printf("%I64d\n",v[i]);
87         }
88     }
89     return 0;
90 }

 

转载于:https://www.cnblogs.com/njczy2010/p/4409111.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值