算法思想求: “单源最短路径” 的经典算法
1.核心目标是:在无负权边的图中(有向 / 无向均可),高效找到起点到所有节点的最短路径。
2.每次选择距离(原点集)最近的点,加入原点集(标记)
3.更新各点到原点最近距离
条件:图中所有边的权重都是非负数
题目
https://kamacoder.com/problempage.php?pid=1047
代码(朴素)
include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=501;
int pic[N][N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>m;
for(int i=0;i<m;i++)
{
int a,b,c;
cin>>a>>b>>c;
pic[a][b]=c;
}
vector
vector
dis[1]=0;
for(int i=1;i<=n;i++)
{
int mindis=INT_MAX;
int cur=0;
for(int j=1;j<=n;j++)
{
if(!isuse[j]&&dis[j]<mindis)
{
mindis=dis[j];
cur=j;
}
}
isuse[cur]=1;
for(int k=1;k<=n;k++)
{
if(!isuse[k]&&pic[cur][k]!=0&&(dis[cur]+pic[cur][k]<dis[k]))
{
dis[k]=dis[cur]+pic[cur][k];
}
}
}
if(dis[n]==INT_MAX)
{
cout<<-1;
return 0;
}
cout<<dis[n];
return 0;
}
堆优化(可以将每次找到原点集最近的点步骤省略)
include<bits/stdc++.h>
using namespace std;
int n,m;
class mycomparision
{
public:
bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs)
{
return lhs.second>rhs.second;
}
};
struct Edge
{
int to;
int val;
Edge(int t,int w):to(t),val(w){}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int p1,p2,val;
cin>>n>>m;
vector<list
for(int i=0;i<m;i++)
{
cin>>p1>>p2>>val;
grid[p1].push_back(Edge(p2,val));
}
int start=1;
int end=n;
vector
vector
priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparision>pq;
pq.push(pair<int,int>(start,0));
minDist[start]=0;
while(!pq.empty())
{
pair<int,int> cur=pq.top();
pq.pop();
if(visited[cur.first])continue;
visited[cur.first]=1;
for(Edge edge:grid[cur.first])
{
if(!visited[edge.to]&&minDist[cur.first]+edge.val<minDist[edge.to])
{
minDist[edge.to]=minDist[cur.first]+edge.val;
pq.push(pair<int,int>(edge.to,minDist[edge.to]));
}
}
}
if(minDist[end] == INT_MAX) cout << -1 << endl; // 不能到达终点
else cout << minDist[end] << endl; //
}
//priority_queue(优先队列->堆)
朴素O(n^2)
堆优化O(mlogn)(m->边,n->点);
浙公网安备 33010602011771号