题目
大意:给你x条双向边和y条单向边,问你这个点中每个点到s点的最小距离(注意:单向边可能为负,所以要用spfa)但是裸的spfa又会tle,这时就要用slf优化
这是我的spfa优化的代码,但是用了容器,还是会tle
#include
#include
#include
#include
#include
#define maxn 25050
#define inf 0x3f3f3f3f
using namespace std;
vector<pair<int,int> >edge[maxn];
int dis[maxn],inqueue[maxn];
int n,x,y,s;
void spfa(int start){
deque<int> q;
q.push_back(start);
dis[start]=0;
inqueue[start]++;
while(!q.empty()){
int now=q.front();
q.pop_front();
inqueue[now]=0;
for(int i=0;i<edge[now].size();i++){
int v=edge[now][i].first;
if(dis[v]>dis[now]+edge[now][i].second){
dis[v]=dis[now]+edge[now][i].second;
if(!q.empty()&&dis[v]>=dis[q.front()]){
q.push_back(v);
}else{
q.push_front(v);
}
inqueue[v]=1;
}
}
}
for(int i=1;i<=n;i++){
if(dis[i]==inf){
printf("NO PATH\n");
}else{
printf("%d\n",dis[i]);
}
}
}
int main(){
memset(inqueue,0,sizeof(inqueue));
memset(dis,inf,sizeof(dis));
scanf("%d%d%d%d",&n,&x,&y,&s);
for(int i=0;i<x;i++){
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
edge[a].push_back(make_pair(b,w));
edge[b].push_back(make_pair(a,w));
}
for(int i=0;i<y;i++){
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
edge[a].push_back(make_pair(b,w));
}
spfa(s);
return 0;
}
一开始我以为是调用vector容器时会用很长时间,后来用链式前向星表示,发现提交到计蒜客时一直显示段错误,后来我去看了别人的题解,发现是deque的问题,应该是deque不能太长,比如这题我试了应该要1e6次方。
代码如下:
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn = 1e6;
struct Edge{
int to,next,w;
}edge[maxn];
int n,x,y,s,tot=1;
int head[maxn];
ll dis[maxn],val;
bool inq[maxn];
void add(int u,int v,int w){
edge[tot].to=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
}
int q[2000100],l,r;
void spfa(){
for(int i=1;i<=n;i++){
dis[i]=1e15;
}
l=r=1e6;
q[l]=s;
dis[s]=0;
inq[s]=true;
while(l<=r){
int now=q[l++];
inq[now]=false;
for(int i=head[now];i;i=edge[i].next){
int v=edge[i].to;
if(dis[v]>dis[now]+edge[i].w){
dis[v]=dis[now]+edge[i].w;
if(!inq[v]){
if(l<=r&&dis[q[l]]+val>=dis[v]){
q[--l]=v;
}else{
q[++r]=v;
}
inq[v]=true;
}
}
}
}
for(int i=1;i<=n;i++){
if(dis[i]==1e15){
printf("NO PATH\n");
}else{
printf("%lld\n",dis[i]);
}
}
}
int main(){
memset(inq,false,sizeof(inq));
scanf("%d%d%d%d",&n,&x,&y,&s);
for(int i=1;i<=x;i++){
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
add(a,b,w);
add(b,a,w);
val+=2*w;
}
for(int i=1;i<=y;i++){
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
add(a,b,w);
val+=w;
}
val=sqrt(val)/100;
spfa();
return 0;
}