求解:为什么spfa AC而堆优化djkstra WA第8个点?

P1462 通往奥格瑞玛的道路

纳尔罕 @ 2018-04-23 23:20:12

用了优先队列优化djkstra,感觉和下面的spfa没什么不同,但第8个点应该输出7万多,却一直输出AFK。求指点。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int N=1e5+5,M=5e5+5;
int n,m,head[N],xnt;
ll b,v[N],l,r,ans=-1,dis[N];
bool vis[N];
struct Edge{
    int next,to;ll w,c;
    Edge(int n=0,int t=0,ll w=0,ll c=0):next(n),to(t),w(w),c(c) {}
}edge[M<<1];
struct Node{
    int bh;ll c;
    Node(int b=0,ll c=0):bh(b),c(c) {}
    bool operator <(const Node &a)const
    {return c<a.c;}
};
void add(int x,int y,ll z)
{
    edge[++xnt]=Edge(head[x],y,z,v[y]);head[x]=xnt;
    edge[++xnt]=Edge(head[y],x,z,v[x]);head[y]=xnt;
}
bool dj(ll mid)
{
    printf("mid=%lld\n",mid);
    memset(dis,11,sizeof dis);
    memset(vis,0,sizeof vis);
    queue<Node> q;
    dis[1]=0;q.push(Node(1,0));
    while(q.size())
    {
        int k=q.front().bh;q.pop();
        while(q.size()&&vis[k])k=q.front().bh,q.pop();
        if(vis[k])break;vis[k]=1;
        for(int i=head[k],v;i;i=edge[i].next)
        {
//          if(edge[i].c<=mid)printf("1");
//          if(dis[v=edge[i].to]>dis[k]+edge[i].w)printf("2");
//          if(dis[k]+edge[i].w<=b)printf("3");printf("v=%d\n",v);
            if(edge[i].c<=mid&&dis[v=edge[i].to]>dis[k]+edge[i].w&&dis[k]+edge[i].w<=b)
            {dis[v]=dis[k]+edge[i].w;q.push(Node(v,dis[v]));if(v==n)return true;}
        }
    }
    return false;
}
bool spfa(ll mid)
{
    memset(dis,11,sizeof dis);
    memset(vis,0,sizeof vis);
    queue<int> q;
    q.push(1);dis[1]=0;vis[1]=1;
    while(q.size())
    {
        int k=q.front();q.pop();vis[k]=0;
        for(int i=head[k],v;i;i=edge[i].next)
        if(edge[i].c<=mid&&dis[v=edge[i].to]>dis[k]+edge[i].w&&dis[k]+edge[i].w<=b)
            {
                dis[v]=dis[k]+edge[i].w;
                if(!vis[v])vis[v]=1,q.push(v);
                if(v==n)return true;
            }
    }
    return false;
}
int main()
{
//  freopen("洛谷1462#8.in","r",stdin);
    scanf("%d%d%lld",&n,&m,&b);int x,y;ll z;
    for(int i=1;i<=n;i++)scanf("%lld",&v[i]),r=max(r,v[i]);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%lld",&x,&y,&z);
        add(x,y,z);
    }
//  printf("l=%lld r=%lld\n",l,r);
    while(l<=r)
    {
        ll mid=((l+r)>>1);
        if(spfa(mid))ans=mid,r=mid-1;
        else l=mid+1;
    }
    if(ans==-1)printf("AFK");
    else printf("%lld",ans);
    return 0;
}

by Night_Aurora @ 2018-04-24 09:55:20

@纳尔罕

你这堆优化不是堆啊... 应该是priority_queue才对


by newbie314159 @ 2018-04-24 17:04:54

真.堆优化


by 纳尔罕 @ 2018-04-24 17:50:08

噗。明白了。


|