前言
这次的这些题感觉就会比前几篇要简单一点了,大多都是是背模板。
一、Dijkstra算法
Dijkstra算法是用在权值无负数的图上,用来找最短距离的算法,时间复杂度为O(m*logm)。
1.模板——网络延迟时间
class Solution {
public:
//邻接表建图
vector<vector<vector<int>>>graph;
static bool cmp(vector<int>&a,vector<int>&b)
{
return a[1]>b[1];
}
int networkDelayTime(vector<vector<int>>& times, int n, int k) {
int m=times.size();
build(n);
//建图
for(int i=0;i<m;i++)
{
graph[times[i][0]].push_back({times[i][1],times[i][2]});
}
vector<int>distance(n+1,INT_MAX);
distance[k]=0;
vector<bool>visited(n+1,false);
priority_queue<vector<int>,vector<vector<int>>,decltype(&cmp)>heap(cmp);
heap.push({k,0});
while(!heap.empty())
{
int u=heap.top()[0];
heap.pop();
if(!visited[u])
{
visited[u]=true;
for(int i=0;i<graph[u].size();i++)
{
int v=graph[u][i][0];
int w=graph[u][i][1];
if(!visited[v]&&distance[u]+w<distance[v])
{
distance[v]=distance[u]+w;
heap.push({v,distance[v]});
}
}
}
}
int ans=INT_MIN;
for(int i=1;i<=n;i++)
{
ans=max(ans,distance[i]);
}
return ans==INT_MAX?-1:ans;
}
void build(int n)
{
graph.resize(n+1);
}
};
Dijkstra算法的过程就是,首先设置distance数组存起点到每个点的最短距离,那么为了每次求最短,所以初始时每个点都设置成无穷大。之后除了还要设置一个visited数组记录来没来过,还要借助一个以distance为排序的小根堆。
之后只要堆不为空,每次取堆顶元素,没来过就去当前节点的所有边看,如果到当前节点的距离加上边权比下一个点的距离更小,即通过这条路能把去下一个节点的距离变得更小,就更新并入堆。
2.模板——【模板】单源最短路径(标准版)
#include<bits/stdc++.h>
using namespace std;
//邻接表建图
vector<vector<vector<int>>>graph;
static bool cmp(vector<int>&a,vector<int>&b)
{
return a[1]>b[1];
}
void build(int n)
{
graph.resize(n+1);
}
void solve(int n,int m,int s,vector<vector<int>>&edges)
{
build(n);
//建图
for(int i=0;i<m;i++)
{
graph[edges[i][0]].push_back({edges[i][1],edges[i][2]});
}
vector<int>distance(n+1,INT_MAX);
distance[s]=0;
vector<bool>visited(n+1,false);
//小根堆
priority_queue<vector<int>,vector<vector<int>>,decltype(&cmp)>heap(cmp);
heap.push({s,0});
while(!heap.empty())
{
int u=heap.top()[0];
heap.pop();
if(!visited[u])
{
visited[u]=true;
for(int i=0;i<graph[u].size();i++)
{
int v=graph[u][i][0];
int w=graph[u][i][1];
if(!visited[v]&&dis