bzoj3408: [Usaco2009 Oct]Heat Wave 热浪

传送门

Description

这里写图片描述

Input

第1行:4个由空格隔开的整数T,C,Ts,Te.
第2到第C+1行:第i+l行描述第i条道路.有3个由空格隔开的整数Rs,Re,Ci.

Output
一个单独的整数表示Ts到Te的最小费用.数据保证至少存在一条道路.
Sample Input

7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1

Sample Output

7

思路

这题吧,其实本身是一道最短路裸体
但是我把它当做dijistra堆优化模板
dijistra堆优化就是想dijistra一样跑每一条边,但是在跑的过程中加一个优先队列
把dis值最小的从队列中提出更新即可

代码

#include <bits/stdc++.h>
#define pa pair<int,int>
using namespace std;
inline int read(){
    int ret=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())ret=(ret<<3)+(ret<<1)+c-'0';
    return ret*f;
}
struct pppp{
    int x,y,val,nxt;
    bool operator > (const pppp a) const{
        return val>a.val;
    }
}a[100005];
priority_queue<pa, vector<pa> , greater<pa> >q;
int n,m,S,T,pp=0,dis[100005],he[100005];
inline void add(int x,int y,int z){
    a[++pp].x=x;a[pp].y=y;a[pp].nxt=he[x];he[x]=pp;a[pp].val=z;
    a[++pp].x=y;a[pp].y=x;a[pp].nxt=he[y];he[y]=pp;a[pp].val=z;
}
int main(){
    int x,y,z;
    n=read();m=read();S=read();T=read();
    for(int i=1;i<=m;++i){
        x=read();y=read();z=read();
        add(x,y,z);
    }
    memset(dis,0x7f,sizeof(dis));
    dis[S]=0;
    q.push(pa(0,S));
    while(!q.empty()){
        x=q.top().second;q.pop();
        if(x==T){
            printf("%d\n",dis[T]);
            return 0;
        }
        for(int i=he[x];i;i=a[i].nxt){
            if(dis[a[i].y]>dis[x]+a[i].val){
                dis[a[i].y]=dis[x]+a[i].val;
                q.push(pa(dis[a[i].y],a[i].y));
            }
        }
    }
    return 0;
}

下面还有一个dijistra的可并堆优化代码
仅供参考

#include <bits/stdc++.h>
#include <ext/pb_ds/priority_queue.hpp>
#define ll long long
#define pa pair<LL,int>  
using namespace std;
using namespace __gnu_pbds;
inline int read(){
    int ret=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())ret=ret*10+c-'0';
    return ret*f;
}
ll n,m,T,rxa,rxc,rya,ryc,rp,pp=0,S;
ll dis[10005];
typedef __gnu_pbds::priority_queue<pa,greater<pa>,pairing_heap_tag > heap;
heap::point_iterator in[10005];
int he[10005];
struct pppp{int nxt,to,val;}a[15001];
inline void add(int x,int y,int z){
    a[++pp].nxt=he[x];
    a[pp].to=y;
    a[pp].val=z;
    he[x]=pp;
}
int main(){
    memset(he,-1,sizeof(he));
    memset(dis,0x7f,sizeof(dis));
    n=read();m=read();int x=0,y=0,z=0,aa,bb;  
    S=read();T=read();
    for(int i=1;i<=m;++i){
        x=read();y=read();z=read();
        add(x,y,z);add(y,x,z);
    }
    dis[S]=0;heap q;
    in[S]=q.push(make_pair(0,S));
    while(!q.empty()){
        int now=q.top().second;q.pop();
        for(int i=he[now];~i;i=a[i].nxt)
            if(a[i].val+dis[now]<dis[a[i].to]){
                dis[a[i].to]=a[i].val+dis[now];
                if(in[a[i].to]!=0)q.modify(in[a[i].to],make_pair(dis[a[i].to],a[i].to));
                else in[a[i].to]=q.push(make_pair(dis[a[i].to],a[i].to));
            }
    }  
    printf("%lld",dis[T]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值