[USACO11JAN] Roads and Planes G
Posted darthvictor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[USACO11JAN] Roads and Planes G相关的知识,希望对你有一定的参考价值。
题目
(Farmer John)正在一个新的销售区域对他的牛奶销售方案进行调查。他想把牛奶送到(T)个城镇((1 <= T <= 25,000)),编号为(1)到(T)。这些城镇之间通过(R)条道路((1 <= R <= 50,000),编号为(1)到(R)) 和(P)条航线 ((1 <= P <= 50,000),编号为(1)到(P)) 连接。每条道路(i)或者航线(i)连接城镇(A_i)((1 <= A_i <= T))到(B_i)((1 <= B_i <= T)),花费为(C_i)。对于道路,(0 <= C_i <= 10,000);然而航线的花费很神奇,花费(C_i)可能是负数((-10,000 <= C_i <= 10,000))。道路是双向的,可以从(A_i)到(B_i),也可以从(B_i)到(A_i),花费都是(C_i)。然而航线与之不同,只可以从(A_i)到(B_i)。事实上,由于最近恐怖主义太嚣张,为了社会和谐,出台了一些政策保证:如果有一条航线可以从(A_i)到(B_i),那么保证不可能通过一些道路和航线从(B_i)回到(A_i)。由于(FJ)的奶牛世界公认十分给力,他需要运送奶牛到每一个城镇。他想找到从发送中心城镇(S(1 <= S <= T))把奶牛送到每个城镇的最便宜的方案,或者知道这是不可能的。
Input
-
第(1)行:四个空格隔开的整数:$ T, R, P,$and (S)
-
第(2)到(R+1)行:三个空格隔开的整数(表示一条道路):(A_i, B_i) 和 (C_i)
-
第(R+2)到(R+P+1)行:三个空格隔开的整数(表示一条航线):(A_i, B_i) 和 (C_i)
Output
- 第(1)到(T)行:从(S)到达城镇(i)的最小花费,如果不存在输出"NO PATH"。
Sample Input
6 3 3 4
1 2 5
3 4 5
5 6 10
3 5 -100
4 6 -100
1 3 -10
样例输入解释:
一共六个城镇。在(1-2,3-4,5-6)之间有道路,花费分别是(5,5,10)。同时有三条航线:(3->5,4->6)和(1->3),花费分别是(-100,-100,-10)。(FJ)的中心城镇在城镇(4)。
Sample Output
NO PATH
NO PATH
5
0
-95
-100
样例输出解释:
(FJ)的奶牛从(4)号城镇开始,可以通过道路到达(3)号城镇。然后他们会通过航线达到(5)和(6)号城镇。
但是不可能到达(1)和(2)号城镇。
解说
幻影忍者前情提要: 这是一个勇敢的少年永不言弃地和时间抗争终于取得了胜利的故事。
首先看一眼题,这不就是很裸的最短路吗?有负边直接跑一遍(SPFA)就完了啊!而且题目保证了没有负环连判断都不用!
之后……(Vjudge)上(T)掉了,洛谷(T)两个点……
[托腮][托腮]
有什么办法可以优化时间效率呢?
经过一番查找,我发现了一种叫做双向对列的优化方法。就是说,在把点入队的时候把目前的距离和队首元素比较一下,如果比队首元素大就推到队尾,否则放在队首,这样的话就可以尽量减少之后的点入队的次数从而达到优化效果。
现在结果如何?(Vjudge)成功卡过了,洛谷还是(T)了一个点。
[托腮][托腮]
再经过我一番查找,我又发现了一种叫做(inline)的东西,加在函数之前好像会快一点。讲解我看了半天没看懂……所以直接用了,然后就(A)了(我无话可说了)。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<string>
#include<queue>
using namespace std;
const int maxn=25000+3,maxe=150000+3,inf=1000000000;
int t,r,p,s,tot,head[maxn],dis[maxn],to[maxe],w[maxe],next[maxe];
bool vis[maxn];
deque<int> q;
void add(int a,int b,int l){
w[++tot]=l;
to[tot]=b;
next[tot]=head[a];
head[a]=tot;
}
inline void Spfa(int begin){
for(int i=1;i<=t;i++) dis[i]=inf;
dis[begin]=0,vis[begin]=1;
q.push_back(begin);
while(!q.empty()){
int u=q.front();
q.pop_front();
vis[u]=0;
for(int i=head[u];i;i=next[i]){
int v=to[i];
if(dis[v]>dis[u]+w[i]){
dis[v]=dis[u]+w[i];
if(!vis[v]){
if(!q.empty()&&dis[v]>=dis[q.front()]) q.push_back(v);
else q.push_front(v);
vis[v]=1;
}
}
}
}
}
int main(){
tot=1;
scanf("%d%d%d%d",&t,&r,&p,&s);
int x,y,w;
for(int i=1;i<=r;i++){
scanf("%d%d%d",&x,&y,&w);
add(x,y,w);
add(y,x,w);
}
for(int i=1;i<=p;i++){
scanf("%d%d%d",&x,&y,&w);
add(x,y,w);
}
Spfa(s);
for(int i=1;i<=t;i++){
if(dis[i]==inf) printf("NO PATH
");
else printf("%d
",dis[i]);
}
return 0;
}
幸甚至哉,歌以咏志。
以上是关于[USACO11JAN] Roads and Planes G的主要内容,如果未能解决你的问题,请参考以下文章
P3008 [USACO11JAN]道路和飞机Roads and Planes
P3008 [USACO11JAN]Roads and Planes G