您的位置:首页 > 其它

codevs 2273 扬帆远洋大战牧师妹酱 SPFA双端队列优化

2016-03-24 11:50 155 查看
根据计算机的计算结果,这N个地点大多都是非常偏僻的城镇。因此,之间的道路并不定都是畅通的。这些地区之间通过R条道路连接,为了使得之间前往的方便,扬帆远洋TEL还帮助扬帆远洋产生了P个空间隧道,扬帆远洋称之为“時間と空間の扉”。每条道路i或者“時間と空間の扉”i连接地区Ai到Bi,花费为Ci。道路是双向的,可以从Ai到Bi,也可以从Bi到Ai,花费都是Ci。然而“時間と空間の扉”与之不同,只可以从Ai到Bi。事实上,由于牧师妹酱的墨镜党(看看我的头像就知道了)的不断干扰使得链接非常不稳定。牧师妹酱的墨镜党的干扰如下:如果有一条“時間と空間の扉”可以从Ai到Bi,那么保证不可能通过一些道路和“時間と空間の扉”从Bi回到Ai。所以有些地区可能无法到达,需要扬帆远洋对自己进行Teleport才可以。

扬帆远洋现在呆在S城镇,由于他需要把每个“れいじまいご·ベクトル変換”的装置调整完毕,因此扬帆远洋写了一个程序计算从S出发,对于每个地区而言计算出了最小的花费,如果不可能,则输出“Need Teleport To Repair”。最后输出,一共有多少个地方是需要用Teleport的。

但是由于墨镜党不断的捣乱,这个程序现在无法工作,请你复述出来这个程序。

输入描述 Input Description

第1行有四个空格隔开的整数T、R、P和S。

第2至R+1行每行有3个空格隔开的正整数,表示一条道路的Ai、Bi和Ci。

第R+2至R+P+1行每行有3个空格隔开的正整数,表示一条“時間と空間の扉”的Ai、Bi和Ci。

输出描述 Output Description

第1到T行每行输出的是从S到达地区i的最小花费,如果不存在输出“Need Teleport To Repair”(没有引号)。

最后一行为一共有多少个地方是需要用Teleport的。

样例输入 Sample Input

6 3 3 4

1 2 5

3 4 5

5 6 10

3 5 -100

4 6 -100

1 3 -10

样例输出 Sample Output

Need Teleport To Repair

Need Teleport To Repair

5

0

-95

-100

2

数据范围及提示 Data Size & Hint

1≤T≤25000,1≤R≤50000,1≤P≤50000,1≤S≤T

1≤Ai≤T,1≤Bi≤T,-10000≤Ci≤10000(对于“時間と空間の扉”来说花费才可能是负数)

这道题题意就是没负环的图,跑SPFA最短路,重点是在数据范围,需要双端队列优化

优化就是如果对一个点更新,最短路比当前队首还要小,就直接加在队首,要不就加在队尾,然后用STL解决就可以。。。。

据说可以省15%~20%时间。这道题多过两个点,就A掉了。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
deque<int> q;
struct bian
{
int from,to,quan;
}b[1500050];
int nxt[250050];
int first[250050];
int tot=1,inf=214748364;
void build(int f,int t,int d)
{
b[tot++].from=f;
b[tot].to=t;
b[tot].quan=d;
nxt[tot]=first[f];
first[f]=tot;
}
int use[250050];
int d[250050];
int main()
{
int t,r,p,s;
scanf("%d%d%d%d",&t,&r,&p,&s);
int x,y,z;
for(int i=1;i<=r;i++)
{
scanf("%d%d%d",&x,&y,&z);
build(x,y,z);
build(y,x,z);
}
for(int i=1;i<=p;i++)
{
scanf("%d%d%d",&x,&y,&z);
build(x,y,z);
}
for(int i=1;i<=t;i++)
d[i]=inf;
d[s]=0;q.push_front(s);
use[s]=1;
int dq,v;
int fro;
bool h=0;
while(q.size()!=0)
{
dq=q.front();
q.pop_front();
use[dq]=0;
for(int i=first[dq];i;i=nxt[i])
{
v=b[i].to;
if(d[v]>d[dq]+b[i].quan)
{
d[v]=d[dq]+b[i].quan;
if(!use[v])
{
use[v]=1;
if(q.size()!=0)
{
h=1;
fro=q.front();
}
if(h==1&&d[v]<d[fro])
{
q.push_front(v);
h==0;
}
else
q.push_back(v);
}
}
}
}
int ans=0;
for(int i=1;i<=t;i++)
{
if(d[i]==inf)
{
printf("Need Teleport To Repair\n");
ans++;
}
else
printf("%d\n",d[i]);
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: