/*************************************************************************
File Name: str.cpp
Author: yubo
Mail: yuzibode@126.com
Created Time: 2014年05月02日 星期五 04时55分27秒
学习重点:
1.dijsktra:用到了图结构,有向图edges[i][j]表示从定点i到定点j的权值
在输入的时候edges[i][j]=edges[j][i]=c,就可以计算无向图的
2.原点可以随意指定,dis数组保存的是从原点到各点的最小距离
3.sum up:先定于一点v, 然后一个for循环,将与定点v直接联系的定点的距离
赋给dis,借此机会把s集合清0,从v开始,同时置s【v】=1,表示v进入集合s依次
进行。既然把从原点到各点的最短距离求出来了,害怕到固定点吗?直接定位dist[i]输出就可以了啊。两者的时间复杂度都是n^2.
保存路径的问题也已经解决,算法中数组prev[i]记录的是从源点到顶点i的最短路径上i的前一个顶点。初始化时,对所有与源点有直接关联的点置prev[i]=v,然后在更新长度是令prev【i】=u。保存后怎么利用呢,比如我想知道从源点1到3的路径,是这样的:
k=1;short【k】=3;从这个点往前推,prev[short[k]]==0为止,最后倒序输出就行了。
那么单个点同样直接定位。
4.现在实现了把路径给弄出来了,只能说代码太帅了
5.限用条件:权值只能是非负的;每条路径只能有一条边
.作为模板,需要自己改动
************************************************************************/
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
int edges[100][100];
int dis[100];//存储路径长度
int s[100];//集合s,数组随题意改变啊
int prev[100];//保存结点的前点
#define MAXN 100000000
int n,m;
void dijkstra(int v)
{
printf("hjfgu\n");
for(int i=1;i<=n;i++)
{
dis[i]=edges[v][i];
s[i]=0;
if(dis[i]==MAXN)
prev[i]=0;//注意在设置数组的时候,如果顶点是从0开始的,这里jiu要
//做修改
else
prev[i]=v;//这说明是直接相关联的
}
dis[v]=0;s[v]=1;//原点已经加入到集合中
for(int i=1;i<n;i++)//Be carefully
{
int temp=MAXN;
int u=v;
for(int j=1;j<=n;j++)//千万
{
if((!s[j])&&(dis[j]<temp))
{
u=j;temp=dis[j];
}
}
s[u]=1;
for(int j=1;j<=n;j++)
{
if((!s[j])&&(edges[u][j]<MAXN)){
if(dis[j]>dis[u]+edges[u][j])//确定一点u后,并不算完,还要
//根据u更新edges【u】【j】和dis
//[u],这也是重点
dis[j]=dis[u]+edges[u][j];
prev[j]=u;
}
}
}
printf("%d\n",dis[1]);
}
int main()
{
freopen("in.txt","r",stdin);
int a,b,c;
int shortest[100];
while(cin>>n>>m){//输入结点数和边数
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
edges[i][j]=MAXN;
}
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
edges[b][a]=edges[a][b]=c;//修改这里可以变为有向图
}
int i;
dijkstra(1);
// 在这里运用了倒向追踪的方法,That's what?
for( i=2;i<=n;i++)
{
printf("%d\t",dis[i]);//输出各顶点时存放的序号
memset(shortest,0,sizeof(shortest));
int k=1;//
shortest[k]=i;
while(prev[shortest[k]]!=0)
{
k++;
shortest[k]=prev[shortest[k-1]];
}
// k++;
shortest[k]=1;
for(int j=k;j>1;j--)
printf("%d-->",shortest[j]);
printf("%d\n",shortest[1]);
}
}
}
dijkstra 模板
最新推荐文章于 2021-04-14 19:54:33 发布