优先队列进阶2018-09-06

优先队列是什么呢?
答(参考度娘):在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。通常采用堆数据结构来实现。
更高级的一些操作请参考:https://blog.csdn.net/cnyali/article/details/78091532 (无敌强者的blog)
现在,我们做点高难度的题吧!!!
两题:https://www.luogu.org/problemnew/show/P4779
https://www.luogu.org/problemnew/show/P3371
这里就需要用到一些堆优化了,既然说会卡SPFA,所以,就可以用prim来做:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+5,inf=1000000000+5,maxm=1000000+5;
int to[maxm],beg[maxn],nex[maxm],d[maxn],p[maxn],w[maxm],n,m,s,e;
priority_queue<pair<int,int>>q;
void add(int x,int y,int z){
    e++;
    to[e]=y;
    nex[e]=beg[x];
    beg[x]=e;
    w[e]=z;
}
int main(){
    cin>>n>>m>>s;
    for(int i=1;i<=m;i++){
        int x,y,z;
        cin>>x>>y>>z;
        add(x,y,z);
    }
    for(int i=1;i<=n;i++)
        d[i]=inf;
    d[s]=0;
    q.push(make_pair(0,s));
    while(q.size()){
        int x=q.top().second;
        q.pop();
        if(p[x])
           continue;
        p[x]=1;
        for(int i=beg[x];i;i=nex[i]){
            int y=to[i],z=w[i];
            if(d[y]>d[x]+z){//可以替换
                d[y]=d[x]+z;
                q.push(make_pair(-d[y],y));//注意,这里必须是负数
            }
        }
    }
    for(int i=1;i<=n;i++)
        if(d[i]==inf)
            cout<<2147483647<<" ";
        else 
            cout<<d[i]<<" ";
    return 0;
}

还有一道题:https://www.luogu.org/problemnew/show/P2865
这里就直接附上代码了:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int i,j,k,n,m,s,len;
int vis[15010];
int vis_[15010];
int dis[15010];
int head[200010];
struct stu{
    int next_,to,w,t;
}c[200010];
void add(int u,int y,int o){
    c[++len].next_=head[u];
    c[len].to=y;
    c[len].w=o;
    c[len].t=u;
    head[u]=len;
}
priority_queue <pair<int,int> > dl;
int main(){
    cin>>n>>m;
    s=1;
    for(int i=1;i<=m;i++){
        int u,y,o;
        scanf("%d%d%d",&u,&y,&o);
        add(u,y,o);
        add(y,u,o);
    }
    for(int i=1;i<=n;i++)
        vis[i]=INF;
    vis[s]=0;
    while(!dl.empty())
       dl.pop();
    dl.push(make_pair(0,s));
    while(!dl.empty()){
        int u=dl.top().second;
        dl.pop();
        if(dis[u])
           continue;
        dis[u]=1;
        for(i=head[u];i;i=c[i].next_){
            int v=c[i].to;
            if(vis[v]>vis[u]+c[i].w){
                vis[v]=vis[u]+c[i].w;
                dl.push(make_pair(-vis[v],v));
            }
        }
    }
    s=n;
    for(int i=1;i<=n;i++)
        vis_[i]=INF;
    memset(dis,0,sizeof(dis));
    while(!dl.empty())
       dl.pop();
    vis_[s]=0;
    dl.push(make_pair(0,s));
    while(!dl.empty()){
        int u=dl.top().second;
        dl.pop();
        if(dis[u])
            continue;
        dis[u]=1;
        for(int i=head[u];i;i=c[i].next_){
            int v=c[i].to;
            if(vis_[v]>vis_[u]+c[i].w){
                vis_[v]=vis_[u]+c[i].w;
                dl.push(make_pair(-vis_[v],v));
            }
        }
    }
    int s1=vis[n],s2=1e9;
    for(int i=1;i<=len;i++){
        int sum=vis[c[i].t]+vis_[c[i].to]+c[i].w;
        if(sum>1e9)
           continue;
        if(sum==s1)
           continue;
        if(sum<s2)
            s2=sum;
    }
    cout<<s2<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42875611/article/details/82467477