//<<算法导论>>求最短路--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
*/