P3008 [USACO11JAN]Roads and Planes G
Posted 2004-08-20
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3008 [USACO11JAN]Roads and Planes G相关的知识,希望对你有一定的参考价值。
不要问我为啥不加天数了,问就是数不过来了
题目大意
Farmer John 正在一个新的销售区域对他的牛奶销售方案进行调查。他想把牛奶送到 T个城镇 ,编号为 1到T 。这些城镇之间通过R 条道路(编号为1 到 R)和 条航线(编号为 1到 P)连接。每条道路 i或者航线i 连接城镇Ai 到 Bi,花费为Ci 。
对于道路0<=Ci<=104,然而航线的花费很神奇,花费Ci可能是负数。道路是双向的,可以从Ai到Bi,也可以从Bi到Ai,话费都是Ci,然而航线与之不同,只可以Ai到Bi。
事实上,由于最近恐怖主义太嚣张,为了社会和谐,出台了一些政策保证:如果有一条航线可以从Ai到Bi,那么保证不可能通过一些道路和航线从Bi回到Ai。由于 FJ 的奶牛世界公认十分给力,他需要运送奶牛到每一个城镇。他想找到从发送中心城镇S把奶牛送到每个城镇的最便宜的方案,或者知道这是不可能的。
输入格式
第一行为四个空格隔开的整数:T,R,P,S;
第二到第R+1行:三个空格隔开的整数(表示一条道路):Ai,Bi和Ci;
第R+2到R+P+1行:三个空格隔开的整数(表示一条航线):Ai,Bi和Ci。
输出格式
输出T行,第i行表示到达城镇i的最小花费,如果不存在输出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
数据范围与提示
对于全部数据,1<=T<=2.5×104,1<=R,P<=5×104,1<=Ai,Bi,S<=T,保证对于所有的道路,0<=Ci<=104,对于所有的航线,-104<=Ci<=104.
算法分析:
- 这题再看不出来是SPFA就该吃**了
- 但是挂了
- 这个题用SPFA会T掉 (加上队列优化一样会T掉) , 所以我们需要别的优化:STL
- STL主要利用双端队列优化
代码展示
//不加STL优化会T到88分 加STL会不会T主要看脸………… 建议交之前洗把脸 (如果一次T了就多交两次)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int head[maxn],cnt;
int dis[maxn],vis[maxn];
struct node{
int next,to,dis;
}a[maxn];
void add(register int x,int y,int z){
a[++cnt].to = y;
a[cnt].dis = z;
a[cnt].next = head[x];
head[x] = cnt;
}
int read(){
char ch=getchar();int ans=0,p=1;
while(ch>‘9‘||ch<‘0‘){
if(ch==‘-‘) p=-1;
ch=getchar();
}
while(ch<=‘9‘&&ch>=‘0‘){
ans=(ans<<1)+(ans<<3)+ch-‘0‘;
ch=getchar();
}
return ans*p;
}
void spfa(register int x){
memset(dis,0x3f,sizeof(dis));
deque<int> q;q.push_back(x),dis[x]=0;//双端队列
while(!q.empty())
{
int now=q.front();q.pop_front();
vis[now]=0;
for(register int i=head[now];i;i=a[i].next)
{
int v=a[i].to;
if(dis[v]>dis[now]+a[i].dis)
{
dis[v]=dis[now]+a[i].dis;
if(!vis[v])
{
vis[v]=1;
if(!q.empty()&&dis[v]<dis[q.front()]) q.push_front(v);//双端队列优化 将距离最小的放在队首(优化效果有点玄学 但是平均优化在15% ~ 20%之间)
else q.push_back(v);
}
}
}
}
}
int main(){
int n = read(),r = read(),p = read(),s = read();
for(register int i = 1;i <= r;++i){
int x = read(),y = read(),w = read();
add(x,y,w);
add(y,x,w);
}
for(register int i = 1;i <= p;++i){
int x = read(),y = read(),w = read();;
add(x,y,w);
}
spfa(s);
for(register int i = 1;i <= n;++i){
if(dis[i] == 0x3f3f3f3f){printf("NO PATH
");continue;}
printf("%d
",dis[i]);
}
return 0;
}
附: 竞赛SPFA常用STL优化 不仅好写而且优化效果比较明显 还有第二种优化是LLL 但是竞赛中不常用(不好写) 可以自行百度扩展 (STL + LLL俩一起用大概优化在50%左右)
以上是关于P3008 [USACO11JAN]Roads and Planes G的主要内容,如果未能解决你的问题,请参考以下文章
P3008 [USACO11JAN]Roads and Planes G
[USACO11JAN] Roads and Planes G
[USACO11JAN]Roads and Planes G缩点+Dij+拓补排序