Floyd-Warshall方法求有向图的传递闭包

有向图G的传递闭包定义为:G*=(V,E*),其中
E*={(i,j)}:图G中存在一条从i到j的路径。

在floyd-warshall求每对顶点间的最短路径算法中,可以通过O(v^3)的方法求出图的传递闭包。可以位每条边赋以权值1,然后运行Floyd-Wareshall。如果从i    到j存在一条路径,则d(i,j)<N,否则d(i,j)=MAX。
 一种改进的算法是:由于我们需要的只是判断是否从i到j存在一条通路,所以在Floyd-Wareshall中的动态规划比较中,我们可以把min和+操作改为逻辑or(||    )和逻辑与(&&)。
 设tk(i,j)=1表示从i到j存在一条通路p,且p的所有中间节点都在0,1,2,...,k中,否则tk(i,j)=0。我们把边(i,j)加入到E*中当且仅当tn(i,j)=1。#include <iostream> using namespace std; const int N = 4; const int E = 5; const int MAX = 0xffff; int ** g; int ** transitive_closure(int **g) { int i = 0; int j = 0; int **t = new int*[N];//tk(i,j)=1表示从顶点i到顶点j存在一条路经,且路径中间节点在0,1,2,...,k中 /* * t-1(i,j) = 0如果i!=j且g[i][j] == MAX,否则t0(i,j) =1. * * tk(i,j) = tk-1(i,j) || (tk-1(i,k)&&tk-1(j,k))当0<=k<N */ for(i=0;i<N;i++) t[i] = new int[N]; for(i=0;i<N;i++)//当k==-1时,即从i到j没有中间节点时,初始化t-1(i,j) for(j=0;j<N;j++) if(i==j || g[i][j] < MAX) t[i][j] = 1; else t[i][j] = 0; int **t1,**t2;//t1表示迭代中的tk-1,t2表示迭代中的tk t1 = t; int k = 0; for(k=0;k<N;k++) { t2 = new int *[N]; for(i=0;i<N;i++) { t2[i] = new int[N]; for(j=0;j<N;j++) { t2[i][j] = t1[i][j] || (t1[i][k] && t1[k][j]); } } for(i=0;i<N;i++) delete []t1[i]; delete []t1; t1 = t2; } return t1; } int main() { int i = 0; int j = 0; g = new int *[N]; for(i=0;i<N;i++) { g[i]= new int[N]; } 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 ** t = transitive_closure(g); for(i=0;i<N;i++) { for(j=0;j<N;j++) cout << t[i][j] << " "; cout << endl; } }  

你可能感兴趣的:(c,算法,delete,ini)