您的位置:首页 > 其它

每对顶点间的最短路径之二——floyd warshall 收藏

2009-09-13 21:56 471 查看
view plaincopy to clipboardprint?
#include <iostream>
using namespace std;
const int N = 5;
const int E = 9;
const int MAX = 0xffff;
int ** g;
/*
* 函数返回Dn-1,其中Dk(i,j)表示顶点i到顶点j的“中间顶点都属于0,1,2,...,k”的最短路径p。
* 于是存在这样的子结构:
* Dk(i,j) =
* min{ Dk-1(i,j), Dk-1(i,k)+Dk-1(k,j)} k>=0
* g[i][j] k<0
* 对于k>=1的情况,如果Dk-1(i,j)<Dk-1(i,k)+Dk-1(k,j),说明从顶点i到顶点j的最短路径p中所有中间顶点都属于0,1,2,...,k-1,k不是路径p的中间节点。否则,如果k是路径p的中间节点,于是路径p分为i->k的p1和k->j的p2,而p1和p2具有相同的性质:p1和p2分别时i到k和k到j的最短路径,并且p1和p2的中间节点都属于0,1,2,...,k-1。于是便有了公式Dk-1(i,k)+Dk-1(k,j)
*
*/
int** floyd_warshall(int ** g)
{
int i = 0,j=0;
int ** d = new int*
;
int **pre = new int*
;
//初始化D-1 = G;
//pre[i][j]表示从顶点i到顶点j的一条最短路径上顶点j的前驱
for(i=0;i<N;i++)
{
d[i] = new int
;
pre[i] = new int
;
for(j=0;j<N;j++)
{
d[i][j] =g[i][j];
if(i==j || g[i][j] == MAX)//初始化pre[i][j]
pre[i][j] = -1;
else
pre[i][j] = i;
}
}
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
cout << pre[i][j] << " " ;
cout << endl;
}
cout << endl;
int k = 0;
/*
* 在此处迭代时,d1代表dk-1,d2代表dk
*/
int ** d1,**d2;
int **p1,**p2;
d1=d;
p1 = pre;
for(k=0;k<N;k++)
{
d2 = new int *
;
p2 = new int*
;
for(i=0;i<N;i++)
{
d2[i] = new int
;
p2[i] = new int
;
}
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
int tmp1 = d1[i][j];
int tmp2 = d1[i][k] + d1[k][j];
if(tmp1<=tmp2)//注意这里的<=
{
d2[i][j] = tmp1;
p2[i][j] = p1[i][j];
}
else
{
d2[i][j] = tmp2;
p2[i][j] = p1[k][j];
}
}
for(i=0;i<N;i++)
{
delete []d1[i];
delete []p1[i];
}
delete []d1;
delete []p1;
d1 = d2;
p1 = p2;
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
cout << p1[i][j] << " " ;
cout << endl;
}
cout << endl;
}
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
cout << p1[i][j] << " " ;
cout << endl;
}
cout << endl;
return d1;
}
int main()
{
int i = 0;
int j = 0;
g = new int *
;
for(i=0;i<N;i++)
{
g[i]= new int
;
}
for(i=0;i<N;i++)
for(j=0;j<N;j++)
if(i==j)
g[i][j] = 0;
else
g[i][j] = MAX;
int c = 0;
while(c<E)
{
cin >> i;
cin >> j;
cin >> g[i][j];
c++;
}
int **d;
d = floyd_warshall(g);
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
cout << d[i][j] << " " ;
cout << endl;
}
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/clearriver/archive/2009/09/13/4548244.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: