女性做网站semantics
P1339 [USACO09OCT] Heat Wave G
题目描述
有一个 n n n 个点 m m m 条边的无向图,请求出从 s s s 到 t t t 的最短路长度。
输入格式
第一行四个正整数 n , m , s , t n,m,s,t n,m,s,t。
接下来 m m m 行,每行三个正整数 u , v , w u,v,w u,v,w,表示一条连接 u , v u,v u,v,长为 w w w 的边。
输出格式
输出一行一个整数,表示答案。
输入输出样例 #1
输入 #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 ≤ 2500 1\le n \le 2500 1≤n≤2500, 1 ≤ m ≤ 6200 1\le m \le 6200 1≤m≤6200, 1 ≤ w ≤ 1000 1\le w \le 1000 1≤w≤1000。
【样例说明】
5 → 6 → 1 → 4 5 \to 6 \to 1 \to 4 5→6→1→4 为最短路,长度为 3 + 1 + 3 = 7 3+1+3 = 7 3+1+3=7。
数据量小,可以用各种方法,数据量大,邻接表优先,其次时间需要优化(最短路堆优化)
堆优化的意义:O(n2)->O(mlog(n))
下面直接上代码
一维模拟邻接表(最难理解):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int w[N];
int e[N];
int h[N];
int ne[N];
int dis[N];
int is[N];
int n,m,qq,zz;
int q=0;
void jb(int a,int b,int c){w[q]=c;e[q]=b;ne[q]=h[a];h[a]=q++;
}
void dij(){memset(dis,0x3f,sizeof(dis));dis[qq]=0;for(int i=0;i<n;i++){int t=-1;for(int j=1;j<=n;j++){if(!is[j]&&(t==-1||dis[j]<dis[t])){t=j;}}is[t]=1;for(int j=h[t];j!=-1;j=ne[j]){int k=w[j];dis[e[j]]=min(dis[e[j]],dis[t]+k);}}
}
int main() {memset(h,-1,sizeof(h));cin>>n>>m>>qq>>zz;for(int i=0;i<m;i++){int a,b,c;cin>>a>>b>>c;jb(a,b,c);jb(b,a,c);}dij();cout<<dis[zz];
}`
邻接表+邻接矩阵(压力给到内存):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+10;
int g[N][N];
vector<int>s[N];
int dis[N];
int is[N];
int n,m,q,z;
void dij(){memset(dis,0x3f,sizeof(dis));dis[q]=0;for(int i=0;i<n;i++){int t=-1;for(int j=1;j<=n;j++){if(!is[j]&&(t==-1||dis[j]<dis[t])){t=j;}}is[t]=1;for(int k=0;k<s[t].size();k++){dis[s[t][k]]=min(dis[s[t][k]],dis[t]+g[t][s[t][k]]);}}
}
int main() {//memset(g,0x3f,sizeof(g));cin>>n>>m>>q>>z;for(int i=0;i<m;i++){int a,b,c;cin>>a>>b>>c;g[a][b]=c;g[b][a]=c;s[a].push_back(b);s[b].push_back(a);}dij();cout<<dis[z];return 0;
}
邻接表(容易理解):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
struct f{int w;int e;
};
vector<f>s[N];
int dis[N];
int is[N];
int n,m,qq,zz;
void dij(){memset(dis,0x3f,sizeof(dis));dis[qq]=0;for(int i=0;i<n;i++){int t=-1;for(int j=1;j<=n;j++){if(!is[j]&&(t==-1||dis[j]<dis[t])){t=j;}}is[t]=1;for(int j=0;j<s[t].size();j++){f z=s[t][j];dis[z.e]=min(dis[z.e],dis[t]+z.w);}}
}
int main() {//memset(g,0x3f,sizeof(g));cin>>n>>m>>qq>>zz;for(int i=0;i<m;i++){int a,b,c;cin>>a>>b>>c;f z;z.e=b;z.w=c;s[a].push_back(z);z.e=a;s[b].push_back(z);}dij();cout<<dis[zz];
}