洛谷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 25001≤n≤2500,1≤m≤62001\le m \le 62001≤m≤6200,1≤w≤10001\le w \le 10001≤w≤1000。
【样例说明】
5→6→1→45 \to 6 \to 1 \to 45→6→1→4 为最短路,长度为 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; }