非负权单源最短路
Description
给一个 nn 个点 mm 条边的无向图,求 ss 到 tt 的最短路。
Input
第一行四个由空格隔开的整数 nn、mm、ss、tt 。
之后 mm 行,每行三个正整数 u_iui、v_ivi、w_iwi ,表示一条从 u_iui 到 v_ivi 长度为 w_iwi 的边。
保证:
1 \leq n \leq 25001≤n≤2500 ,1 \leq m \leq 62001≤m≤6200 ,1 \leq u_i, v_i \leq n1≤ui,vi≤n ,1 \leq w_i \leq 10 ^ 91≤wi≤109。
Output
一个整数表示从 ss 到 tt 的最短路的长度,数据保证 ss 与 tt 是连通的。
Sample Input 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
Sample Output 1
7
Source
LOJ
https://oi-wiki.org/graph/shortest-path/
上面是算法讲解;
如果数据再大一点。
用Dijkstra
需要优先队列。
不会,学一波
https://oi-wiki.org/ds/stl/priority_queue/
这里有讲解。
也可以去看看别人的博客;
#include <iostream>
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
#define maxn 2510
bool inqueen[3001];
struct Edge{
int v,cost;
};
ll dis[3001],inf=ll(1e18);
vector<Edge> edge[maxn];
int main()
{
int n,m,s,t,u,v,w;
scanf("%d %d %d %d",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&u,&v,&w);
edge[u].push_back({v,w});
edge[v].push_back({u,w});
}
queue<int>Q;
for(int i=1;i<=n;i++)
{
dis[i]=inf;
}
memset(inqueen,false,sizeof(inqueen));
dis[s]=0;
Q.push(s);
inqueen[s]=true;
while(!Q.empty()){
int b=Q.front();
Q.pop();
//printf("%d\n",b);
inqueen[b]=false;
int size=int(edge[b].size());
for(int i=0;i<size;i++)
{
int v=edge[b][i].v,cost=edge[b][i].cost;
if(dis[v]>dis[b]+cost){
dis[v]=dis[b]+cost;
if(!inqueen[v]){
Q.push(v);
inqueen[v]=true;
}
}
}
}
printf("%lld\n",dis[t]);
return 0;
}
#include <iostream>
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
bool inqueen[2510];
ll dis[2510],inf=ll(1e18);
int a[2510][2510];
int main()
{
int n,m,s,t,u,v,w;
scanf("%d %d %d %d",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&u,&v,&w);
a[u][v]=w;
a[v][u]=w;
}
for(int i=1;i<=n;i++)
{
dis[i]=inf;
}
memset(inqueen,false,sizeof(inqueen));
dis[s]=0;
queue<int>Q;
Q.push(s);
inqueen[s]=true;
while(!Q.empty()){
int b=Q.front();
Q.pop();
//printf("%d\n",b);
inqueen[b]=false;
for(int i=1;i<=n;i++)
{
if(a[b][i]>0&&dis[i]>dis[b]+a[b][i])
{
dis[i]=dis[b]+a[b][i];
if(!inqueen[i])
{
Q.push(i);
inqueen[i]=true;
}
}
}
}
printf("%lld\n",dis[t]);
return 0;
}
一种是邻接矩阵,一种是邻接表
下面是Dijkstra;
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,m,s,t;
typedef long long ll;
const int N =100001;
ll dist[N],inf=ll(1e18);
bool inque[N];
struct edge
{
int v;
int time;
};
struct youxian{
int index;
ll dist;
bool operator<(const youxian &tmp)
const {
return dist>tmp.dist;
}
};
vector<edge>e[N];
ll fun()
{
int i;
for(i=1;i<=n;i++)
{
dist[i]=inf;
inque[i]=false;
}
dist[s]=0;
priority_queue<youxian>Q;
Q.push({s,0});
while(!Q.empty()){
int u=Q.top().index;
Q.pop();
if(inque[u]) continue;
inque[u]=true;
int size=int (e[u].size());
for(i=0;i<size;i++){
int v=e[u][i].v,time=e[u][i].time;
if(dist[v]>dist[u]+time){
dist[v]=dist[u]+time;
Q.push({v,dist[v]});
}
}
}
return dist[t];
}
int main()
{
int u,v,w;
scanf("%d %d %d %d",&n,&m,&s,&t);
for(int i=0;i<m;i++){
scanf("%d %d %d",&u,&v,&w);
e[u].push_back({v,w});
e[v].push_back({u,w});
}
printf("%lld\n",fun());
return 0;
}