HAUTOJ 1262魔法宝石 优先队列

题目链接


比赛场上是暴力怼过去的,回来补题学了个优先队列的想法

因为宝石的合成情况可能有嵌套,比如1和2生成3,1和3生成2,2和3生成1,如果用dp去做的话,那么就会形成一个回路,就没办法当做树形dp搞了



所以我们要想到,如果出现了某个生成环,那么其环三个元素中,魔力值最小的那个一定不可被更新,所以这个环本质上是不影响我们最终最优值的

因此,我们只需要构造一个优先队列,按照所有宝石的魔力值从小到大排序,依次出队列依次对其他点进行更新即可


#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+500;
struct node{
    int value,id;
    friend bool operator < (const node &a,const node &b){
        return a.value < b.value;
    }
}a[maxn];

priority_queue<node> q;

struct Edge{
    int a,b,c,nxt;
}edge[maxn*2];
int head[maxn],tot;
int T,n,m;
int dp[maxn];

void addedge(int a,int b,int c){
    edge[tot].a=a;
    edge[tot].b=b;
    edge[tot].c=c;
    edge[tot].nxt=head[a];
    head[a]=tot++;
}
int main(){
    scanf("%d",&T);
    while(T--){
        while(!q.empty()) q.pop();
        scanf("%d%d",&n,&m);
        memset(head,-1,sizeof(head));
        tot=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i].value);
            a[i].id=i;
            q.push(a[i]);
            dp[i]=a[i].value;
        }
        int x,y,z;
        while(m--){
            scanf("%d%d%d",&x,&y,&z);
            addedge(x,y,z);
            addedge(y,x,z);
        }
        while(!q.empty()){
            node t=q.top();
            int u=t.id;
            q.pop();
            for(int i=head[u];i!=-1;i=edge[i].nxt){
                int v=edge[i].b;
                int w=edge[i].c;
                if (dp[u]+dp[v]<dp[w]){
                    dp[w]=dp[u]+dp[v];
                    node tp;
                    tp.id=w;
                    tp.value=dp[w];
                    q.push(tp);
                }
            }
        }
        for(int i=1;i<=n;i++)
            printf("%d%c",dp[i],i==n?'\n':' ');
    }
    return 0;
}


全部评论

相关推荐

小红书 后端开发 总包n+8w+期权
点赞 评论 收藏
分享
10-17 16:07
门头沟学院 Java
牛牛大你18号:在汇报,突然弹出来,,领导以为我在准备跳槽,刚从领导办公室谈心出来
点赞 评论 收藏
分享
暴走萝莉莉:这是社招场吧,作为HR说个实话:这个维护关系的意思是要有政府资源,在曾经的工作中通过人脉资源拿下过大订单的意思。这个有相关管理经验,意思也是真的要有同岗位经验。应酬什么的对于业务成交来说就算不乐意也是常态,就是要求说话好听情商高,酒量好。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务