#include<cstdio> // S-T集合迪杰斯特拉算法理论
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=1000;
const int inf=1000000000;
int n,g[maxn][maxn];
int d[maxn],pre[maxn],,weight[maxn],w[maxn];
bool vis[maxn]={false};
// 邻接矩阵版
void dijkstra(int s){ //s为起点
fill(d,d+maxn,inf); //将到达源点的距离初始化!
fill(w,w+maxn,0);
for(int i=0;i<n;i++) pre[i]=i;// ***********更新的地方1 初始化pre!
d[s]=0;
w[s]=weight[s]; //起点到起点的物资数量当然是其自身的物资数量
for(int i=0;i<n;i++){ //整体循环n次,通过n步把点加入S集合
int u=-1,min=inf; //u使得d[u]最小,min存放该最小的d[u];
for(int j=0;j<n;j++){ //选出未访问点中到源点距离最小的!
if(vis[j]==false&&d[j]<min){
u=j;
min=d[j];
}
}
if(u==-1) return ;
vis[u]=true;
for(int v=0;v<n;v++){ //围绕除u以外的各点(被动访问)并比较!
if(vis[v]==false && g[u][v]!=inf ){
if(d[u]+g[u][v]<d[v]){
d[v]=d[u]+g[u][v]; //先考虑的是哪条路径最短!
w[v]=w[u]+weight[v]; //再考虑“开销花费”
} else if(d[u]+g[u][v]==d[v] && w[u]+weight[v]>w[v]) { //距离相同时再比较开销花费
w[v]=w[u]+weight[v]; //路径最短的情况下,要得到最多的物资!
}
pre[v]=u;//******************更新的地方2
}
}
}
} // 该核心函数整整 20 行!!!!
//邻接表版
struct node{
int v,dis;
};
vector<node> adj[maxn];
void Djkstra(int s){
fill(d,d+maxn,inf);
for(int i=0;i<n;i++) pre[i]=i;// ***********11111111111
d[s]=0;
for(int i=0;i<n;i++){
int u=-1,min=inf;
for(int j=0;j<n;j++){ //d[]可以使用STL的优先队列 复杂度为O(logV) 总复杂度降低为O(VlogV+E)!
if(vis[j]==false && d[j]<min){
u=j;
min=d[j];
}
}
if(u==-1) return ;
vis[u]=true;
for(int j=0;j<adj[u].size();j++){ //只有此处与邻接矩阵写法不同!
int v=adj[u][j].v; //每个容器内存储的顶点本身就是只有可达的!因此这邻接表
if(vis[v]==false && d[u]+adj[u][j].dis<d[v]){//写法比邻接矩阵法更省时间:O(V^2+E)<O(V^2+v^2)
d[v]=d[u]+adj[u][j].dis;
pre[v]=u; //*****************22222222222
}
}
}
} //21行
void dfs(int s,int v){ //递归——太巧妙了!
if(s==v){
printf("%d ",s);
return ;
}
dfs(s,pre[v]);
printf("%d ",v);
}
int main(){
return 0;
}
迪杰斯特拉(第二种新增点权)
最新推荐文章于 2021-08-02 17:16:32 发布