题解 P5764 【[CQOI2005]新年好】

· · 个人记录

先提醒一下没做这道题的人,这道题加强数据之后朴素以及双端队列优化的 SPFA 是过不去的,朴素的 dijkstra 也过不去。

这篇题解主要是堆优化的(priority+pair)spfa

思路

AC详情

#include<cstdio>
#include<vector>
#include<iostream>
#include<cmath>
#include<queue>
#include<cstring>
#define re register int
using namespace std;
int read(){
    int xxx=0,fu=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')fu=-fu;ch=getchar();}
    while(ch>='0'&&ch<='9')xxx=xxx*10+ch-'0',ch=getchar();
    return xxx*fu;
}

int n,m,a,b,c;
int ma[6][6],cl[6],ans=0x3f3f3f3f;
int aim[6];
struct node{
    int to,val;
};
vector<node>h[50001];

int dfs(int s,int me){
    int ti=0;
    for(re i=1;i<=5;i++){
        if(i==s)continue;
        if(cl[i]==0){
            cl[i]++;
            dfs(i,me+ma[s][i]);
            cl[i]--;
        }
        else ti++;
    }
    if(ti==4)ans=min(ans,me);
    return ans;
}

int vis[50001],d[50001];
typedef pair<int,int>pa;  
priority_queue<pa,vector<pa>,greater<pa> >q;
void priority_spfa(int num,int s){
    memset(d,0x3f3f3f3f,sizeof(d));
    vis[s]=1;d[s]=0;
    q.push(make_pair(0,s));
    while(q.size()!=0){
        int u=q.top().second;
        int x=q.top().first;
        q.pop();vis[u]=0;
        if(x>d[u])continue;
        for(re i=0;i<h[u].size();i++){
            node v=h[u][i];
            if(d[u]+v.val<d[v.to]){
                d[v.to]=d[u]+v.val;
                vis[v.to]=1;
                q.push(make_pair(d[v.to],v.to));
            }
        }
    }
    ma[num][0]=d[1];
    ma[num][1]=d[aim[1]];
    ma[num][2]=d[aim[2]];
    ma[num][3]=d[aim[3]];
    ma[num][4]=d[aim[4]];
    ma[num][5]=d[aim[5]];
}
int main(){
    n=read();m=read();
    for(re i=1;i<=5;i++)aim[i]=read();
    for(re i=1;i<=m;i++){
        a=read();b=read();c=read();
        h[a].push_back((node){b,c});
        h[b].push_back((node){a,c});
    }
    priority_spfa(0,1);
    priority_spfa(1,aim[1]);
    priority_spfa(2,aim[2]);
    priority_spfa(3,aim[3]);
    priority_spfa(4,aim[4]);
    priority_spfa(5,aim[5]);
    printf("%d",dfs(0,0));
    return 0;
}