Loading

洛谷P1339 [USACO09OCT]热浪Heat Wave

题目描述

有一个 nnn 个点 mmm 条边的无向图,请求出从 sss 到 ttt 的最短路长度。

输入格式

第一行四个正整数 n,m,s,tn,m,s,tn,m,s,t。 接下来 mmm 行,每行三个正整数 u,v,wu,v,wu,v,w,表示一条连接 u,vu,vu,v,长为 www 的边。

输出格式

输出一行一个整数,表示答案。

输入输出样例

输入 #1 
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
输出 #1
7

说明/提示

【数据范围】
对于 100%100\%100% 的数据,1≤n≤25001\le n \le 25001n2500,1≤m≤62001\le m \le 62001m6200,1≤w≤10001\le w \le 10001w1000。

【样例说明】
5→6→1→45 \to 6 \to 1 \to 45614 为最短路,长度为 3+1+3=73+1+3 = 73+1+3=7。

跑Floyd会爆,只好敲一发堆优化的Dij板子上去。发这篇主要是提醒自己无向图一定要存双向边,和边数量有关的数组一定要开两倍,要不然会RE!!

#include <bits/stdc++.h>
using namespace std;
int n,m,s,t,tot;
const int N=3000,M=7000;
int head[N],ver[2*M],edge[2*M],Next[2*M],d[N];
bool v[N];
priority_queue<pair<int,int> >q;
void add(int x,int y,int z)
{
    ver[++tot]=y;
    edge[tot]=z;
    Next[tot]=head[x];
    head[x]=tot;
}
void Dijkstra()
{
    memset(d,0x3f3f3f3f,sizeof(d));
    memset(v,0,sizeof(v));
    d[s]=0;
    q.push(make_pair(0,s));
    while(q.size())
    {
        int x=q.top().second;q.pop();
        if(v[x])continue;
        v[x]=1;
        int i;
        for(i=head[x];i;i=Next[i])
        {
            int y=ver[i],z=edge[i];
            if(d[y]>d[x]+z)
            {
                d[y]=d[x]+z;
                q.push(make_pair(-d[y],y));
            }
        }    
    }
}
int main()
{
    cin>>n>>m>>s>>t;
    int i;
    for(i=1;i<=m;i++)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);    
    }
    Dijkstra();
    cout<<d[t];
    return 0;
}

 

posted @ 2020-02-19 21:40  脂环  阅读(323)  评论(0编辑  收藏  举报