求助,蒟蒻的Dij加堆优化+二分答案炸了

P1462 通往奥格瑞玛的道路

_yjh @ 2020-05-17 16:39:02

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
struct Edge {
    long long to,q;
};
struct Pri {
    long long k,q;
};
bool operator < (Pri a,Pri b) {
    return a.q>b.q;
}
long long n,m,b,l,r=-1,p[10005],d[10005];
bool vis[10005],Find,use;
priority_queue <Pri> q;
vector <Edge> v[10005];
int main() {
    ios::sync_with_stdio(false);
    cin>>n>>m>>b;
    for(int i=1;i<=n;i++) {
        cin>>p[i];
        r=max(r,p[i]);
    }
    l=max(p[1],p[n]);
    for(int i=1;i<=m;i++) {
        long long x,y,z;
        cin>>x>>y>>z;
        v[x].push_back((Edge){y,z});
        v[y].push_back((Edge){x,y});
    }
    while(l<=r) {
        if(l==r&&use==true) {
            break;
        }
        use=true;
        long long mid=(l+r)/2;
        for(int i=1;i<=n;i++) {
            d[i]=9223372036854775807;
            vis[i]=false;
            if(p[i]>mid) {
                vis[i]=true;
            }
        }
        d[1]=0;
        q.push((Pri){1,0});
        while(!q.empty()) {
            long long k=q.top().k;
            q.pop();
            if(vis[k]==true) {
                continue;
            }
            vis[k]=true;
            for(int i=0;i<v[k].size();i++) {
                if(p[v[k][i].to]>mid) {
                    continue;
                }
                if(d[k]+v[k][i].q<d[v[k][i].to]) {
                    d[v[k][i].to]=d[k]+v[k][i].q;
                    q.push((Pri){v[k][i].to,d[k]+v[k][i].q});
                }
            }
        }
        if(d[n]<b) {
            l=mid;
            Find=true;
        }
        else {
            r=mid-1;
        }
    }
    if(Find) cout<<l<<'\n';
    else cout<<"AFK"<<'\n';
    return 0;
}

不知道为什么有9个TLE和1个WA,自己也找不出错QAQ


by metaphysis @ 2020-05-17 17:01:11

@_yjh

没看到代码末尾,建图部分有错误。

v[x].push_back((Edge) {y, z});
v[y].push_back((Edge) {x, y});

您先修正这个错误,我再看看其他部分有没有问题。


by _yjh @ 2020-05-17 17:06:50

@metaphysis 谢谢大佬


by metaphysis @ 2020-05-17 18:02:53

@_yjh

有几处问题,先说一个重要的,此处代码容易导致TLE或者WA:

if(d[n]<b) {
            l=mid;
            Find=true;
        }

建议增加一个变量ans记录解,将其改为:

 if(d[n]<=b) {
            l=mid + 1;
            Find=true;
            ans = mid;
        }

我之前的提交是假定d[n]等于b时也算能够到达。

还有一个:

 if (l == r && use == true)
{
break;
}
use = true;

不知此代码是何意义,可否解释一下?

您先改改看,总体思路没有问题的,主要是实现的细节方面有些问题。


|