标签:push 形式 题目 交换 printf ack 收集 全局变量 str
形式:
用来解决单源最短路径的问题,即给出图G和起点s,通过算法到达每个顶点的最短距离。基本思想:
对图G(V, E)设置集合S, 存放已被访问的顶点,然后每次从集合V-S中选择与起点s的最短距离最小的一个顶点u,访问并加入集合S。之后,令顶点u为中介点, 优化起点和所有的从u能到达的顶点v之间的最短距离。这样的操作执行n(顶点的个数)次。伪代码:
//G为图, 一般设置为全局变量,数组d为源点到达各点的最短路径长度,s为起点
Djikstra(G, d[], s){
初始化
for(循环n次){
u = 是d[u]最小的还未被访问的顶点的标号
记u已被访问
for(从u出发能到达的所有顶点v){
if(v未被访问&&以U为中介使得s到顶点v的最短距离d[v]更优){
优化d[v]
}
}
}
}
const int MAXV = 1000;//最大顶点数
const int INF = 10000000000;//设INF为一个很大数
//适用于点数不大的情况
int n, G[MAXV][MAXV];
int d[MAXV];
bool vis[MAXV];
void Dijkstra(int s){
fill(d, d+MAXV, INF);
d[s] = 0;
for(int i = 0; i < n; i++){
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];
}
}
//找不到小于INF的d[u],说明剩下的顶点与s不连通
if(u == -1) return;
vis[u] = true;//标记u为已访问
for(int v = 0; v < n; v++){
//如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
if(vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];//优化d[v]
}
}
}
}
struct node{
int v, dis;//v为边的目标顶点,dis为边权
};
vector<node> Adj[MAXV];
int n;
int d[MAXn];
bool vis[MAXV] = {false};
void Dijkstra(int s){
fill(d, d+MAXV, INF);
d[s] = 0;
for(int i = 0; i < n; i++){
int u = -1, MIN = INF;
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 j = 0; j < Adj[u].size(); j++){
int v = Adj[u][j].v//通过邻接表直接获得u能够到达的v
if(vis[v] == false && d[u] + Adj[u][j].dis < d[v]){
d[v] = d[u] + Adj[u][j].dis;
}
}
}
}
const int MAXV = 1000;//最大顶点数
const int INF = 10000000000;//设INF为一个很大数
//适用于点数不大的情况
int n, G[MAXV][MAXV];
int d[MAXV];
bool vis[MAXV];
int pre[MAXV];//表示从起点到顶点v的最短路径上v的前一个顶点(新添加)
void Dijkstra(int s){
fill(d, d+MAXV, INF);
d[s] = 0;
for(int i = 0; i < n; i++){
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];
}
}
//找不到小于INF的d[u],说明剩下的顶点与s不连通
if(u == -1) return;
vis[u] = true;//标记u为已访问
for(int v = 0; v < n; v++){
//如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
if(vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];//优化d[v]
//就是在这里改变,添加了一条语句
pre[v] = u;//新添加
}
}
}
}
//如何打印,就是递归打印
void dfs(int s, int v){
if(v == s){
printf("%d\n", s);
return;
}
dfs(s, pre[v]);
printf("%d\n", v);
}
for(int v = 0; v < n; v++){
//如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
if(vis[v] == false && G[u][v] != INF){
if(d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];//优化d[v]
c[v] = c[u] + cost[u][v];
}else if(d[u] + G[u][v] == d[v] && c[u] + cost[u][v] < c[v]){
c[v] = c[u] + cost[u][v];
}
}
}
for(int v = 0; v < n; v++){
//如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
if(vis[v] == false && G[u][v] != INF){
if(d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];//优化d[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];
}
}
}
for(int v = 0; v < n; v++){
//如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
if(vis[v] == false && G[u][v] != INF){
if(d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];//优化d[v]
num[v] = num[u];
}else if(d[u] + G[u][v] == d[v]){
num[v] += num[u];
}
}
}
数据结构-图的最短路径之Djikstra算法(迪杰斯特拉算法)
标签:push 形式 题目 交换 printf ack 收集 全局变量 str
原文地址:https://www.cnblogs.com/tsruixi/p/12380430.html