Floyd求最短路+输出路径上节点

//<<算法导论>>求最短路--Floyd
#include <iostream>
#include <cstring>
#include <string>

using namespace std;

#define MAXN 100
#define INF 1000000
#define NIL 0

class Graph
{
public:
	Graph(int num):n(num)
	{	
		int i,j;
		memset(Map,0,sizeof(Map));
		memset(Path,NIL,sizeof(Path));
		for(i=1; i<=n; i++)
			for(j=1; j<=n; j++)
			{
				if(i!=j)
					Map[i][j] = INF;
			}
	}
	Graph(Graph *G)
	{
		int i,j;
		n = G->n;
		for(i=1; i<=n; i++)
			for(j=1; j<=n; j++)
			{
				Map[i][j] = G->Map[i][j];
				Path[i][j] = G->Path[i][j];
			}
	}
	void AddSingleEdge(int start, int end, int weight=1)
	{
		Map[start][end] = weight;
		Path[start][end] = start;
	}
	void AddDoubleEdge(int a, int b, int weight=1)
	{
		AddSingleEdge(a,b,weight);
		AddSingleEdge(b,a,weight);
	}
	void DeleteSingleEdge(int start, int end)
	{
		Map[start][end] = INF;
		Path[start][end] = NIL;
	}
	void DeleteDoubleEdge(int a, int b)
	{
		DeleteSingleEdge(a,b);
		DeleteSingleEdge(b,a);
	}
	void Print()
	{
		int i,j;
		
		for(i=1; i<=n; i++)
		{
			for(j=1; j<=n; j++)
			{
				printf("%9d ",Map[i][j]);
			}
			cout<<endl;
		}
		cout<<endl<<endl;
	}
	void Print_Path()
	{
		int i,j;
		for(i=1; i<=n; i++)
		{
			for(j=1; j<=n; j++)
			{
				printf("%9d ",Path[i][j]);
			}
			cout<<endl;
		}
		cout<<endl<<endl;
	}
	//FloydWarshall函数
	Graph* FloydWarshall(Graph *W);
	//打印i->j路径上经过的结点
	void Print_All_Pairs_Shortest_Path(int i, int j);

	int n;		//记录图中的顶点数目
	int Map[MAXN+4][MAXN+4];
	int Path[MAXN+4][MAXN+4];
};

//工具函数
int min(int a, int b)
{
	return a>b ? b:a;
}


Graph* Graph::FloydWarshall(Graph *W)
{
	int i,j,k;
	Graph *D = new Graph(W);

	for(k=1; k<=n; k++)
	{
		for(i=1; i<=n; i++)
		{
			for(j=1; j<=n; j++)
			{
				if(D->Map[i][k]!=INF && D->Map[k][j]!=INF)
				{
					if((D->Map[i][k]+D->Map[k][j]) < D->Map[i][j])
						D->Path[i][j] = D->Path[k][j];
					D->Map[i][j] = min(D->Map[i][j], D->Map[i][k]+D->Map[k][j]);
				}
			}
		}
		//D->Print();
		//D->Print_Path();
	}

	return D;
}

void Graph::Print_All_Pairs_Shortest_Path(int i, int j)
{
	if(i==j)
		printf("->%d",i);
	else if(Path[i][j] == NIL)
	{
		printf("No path from %d to %d exists\n",i,j);
	}
	else
	{
		Print_All_Pairs_Shortest_Path(i,Path[i][j]);
		printf("->%d",j);
	}
}
#define UNSUBMIT

 int main()
 {
#ifdef UNSUBMIT
	 freopen("data.in", "r", stdin);
#endif
	 int n,m;
	 int start, end, weight;

	 cin>>n>>m;			//输入点与边的个数
	 Graph *W = new Graph(n);
	
	 while(m)
	 {
		 cin>>start>>end>>weight;
		 W->AddSingleEdge(start, end, weight);
		 m--;
	 }

	 Graph *result = new Graph(n);

	 result = W->FloydWarshall(W);
	 result->Print();
	 result->Print_Path();
	 result->Print_All_Pairs_Shortest_Path(3,5);

	 return 0;
 }
/*
//图-算法导论25.2
6 10
1 5 -1
2 1 1
2 4 2
3 2 2
3 6 -8
4 1 -4
4 5 3
5 2 7
6 2 5
6 3 10
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值