POJ 3013 Dijkstra+priority_queue

//时间限制3kms,第一开始用ios::sync_with_stdio(false)
//一直TLE,后来用scanf竟然590ms就过了。。。
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=5e4+10;
#define INF 1000000000000
struct Edge{//链式前向星存图
    int to,next,w;
}edge[maxn<<1];//无向图 双向 所以乘2
int head[maxn];
struct Node{
    int u;
    long long dis;
}now,temp;
bool operator< (Node a,Node b){
    return a.dis>b.dis;
}
int weight[maxn];
bool visit[maxn];
long long dis[maxn];//第一个点到其他点的最小距离,也就是Dijsktra的核心算法
void Dijkstra(int s){
    int i,v;
    dis[s]=0;
    priority_queue<Node> pq;
    temp.dis=0,temp.u=s;
    pq.push(temp);
    while(!pq.empty()){
        temp=pq.top();
        pq.pop();
        if(visit[temp.u]==true)
            continue;
        visit[temp.u]=true;
        for(i=head[temp.u];i!=-1;i=edge[i].next){
            v=edge[i].to;
            if(visit[v]==false&&dis[v]>dis[temp.u]+edge[i].w){
                dis[v]=dis[temp.u]+edge[i].w;
                now.u=v;
                now.dis=dis[v];
                pq.push(now);
            }
        }
    }
}
int main(void) {
#ifndef ONLINE_JUDGE
    freopen("E:\\input.txt","r",stdin);
#endif
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%d",&weight[i]);
        int id=0;
        for(int i=0;i<=n;i++){//初始化
            visit[i]=false;
            dis[i]=INF;
            head[i]=-1;
        }
        int t1,t2,t3;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&t1,&t2,&t3);
            t1--,t2--;
            edge[id].to=t2;
            edge[id].w=t3;
            edge[id].next=head[t1];
            head[t1]=id++;

            edge[id].to=t1;
            edge[id].w=t3;
            edge[id].next=head[t2];
            head[t2]=id++;
        }
        Dijkstra(0);
        long long res=0;
        int i;
        for(i=0;i<n;i++){
            if(dis[i]==INF)
                break;
            res+=dis[i]*weight[i];
        }
        if(i<n)
            printf("No Answer\n");
        else
            printf("%lld\n",res);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值