POJ 3013 Dijkstra

从1节点最短路,,然后再乘一下权值就OK了

//By SiriusRen
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 132000
long long d[N];
int n,m,first[N],next[N],v[N],w[N],tot,a[N],xx,yy,zz,cases;
bool vis[N];
struct Node{int now,weight;}jy;
void add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
bool operator < (Node a,Node b){return a.weight>b.weight;}
void Dijkstra(){
    priority_queue<Node>pq;
    memset(d,0x3f,sizeof(d)),memset(vis,0,sizeof(vis)),d[1]=0;
    jy.now=1,jy.weight=0;pq.push(jy);
    while(!pq.empty()){
        Node t=pq.top();pq.pop();
        if(!vis[t.now])vis[t.now]=1;
        else continue;
        for(int i=first[t.now];~i;i=next[i])
            if(!vis[v[i]]&&d[v[i]]>d[t.now]+w[i]){
                d[v[i]]=d[t.now]+w[i];
                jy.now=v[i],jy.weight=d[v[i]];
                pq.push(jy);
            }
    }
    long long ans=0;
    for(int i=1;i<=n;i++)
        if(d[i]>0x3ffffffff){puts("No Answer");return;}
        else ans+=d[i]*a[i];
    printf("%lld
",ans);
}
signed main(){
    scanf("%d",&cases);
    while(cases--){
        tot=0;memset(first,-1,sizeof(first));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&xx,&yy,&zz);
            add(yy,xx,zz),add(xx,yy,zz);
        }
        Dijkstra();
    }
}

这里写图片描述

原文地址:https://www.cnblogs.com/SiriusRen/p/6532286.html