#include <bits/stdc++.h>
using namespace std;
class Graph{
public:
int n, m;
vector<vector<int>> adj;
vector<vector<int>> W;
vector<vector<int>> predecessor;
Graph(int nodes): adj(nodes), W(nodes, vector<int>(nodes, INT_MAX)),
predecessor(nodes, vector<int>(nodes, -1)){
n = nodes;
m = 0;
for(int i=0; i<n; ++i)
W[i][i] = 0;
}
void addEdge(int u, int v, int weight){
if(u >= n || v >=n || u < 0 || v < 0){
cout<<"Either of the vertices doesn't exists in the graph.\n";
return;
}
W[u][v] = weight;
predecessor[u][v] = u;
adj[u].push_back(v);
++m;
}
void allPairsShortestPath(){
for(int k = 0; k < n; ++k){
for(int i = 0; i < n; ++i){
for(int j = 0; j < n; ++j){
if(W[i][k] != INT_MAX && W[k][j] != INT_MAX && W[i][k] + W[k][j] < W[i][j]){
W[i][j] = W[i][k] + W[k][j];
predecessor[i][j] = k;
}
}
}
// for(auto row: W){
// cout<<"|\t";
// for(auto col: row){
// cout<<col<<"\t|\t";
// }
// cout<<"\n";
// }
// cout<<"-------------------------------\n";
}
cout<<"Final distance matrix(with rows/cols indexed [0-"<<n-1<<"]):\n";
for(auto row: W){
cout<<"|\t";
for(auto col: row){
cout<<col<<"\t|\t";
}
cout<<"\n";
}
cout<<"-------------------------------\n"
"Predecessor matrix(with rows/cols indexed [0-"<<n-1<<"]):\n";
for(auto row: predecessor){
cout<<"|\t";
for(auto col: row){
cout<<col<<"\t|\t";
}
cout<<"\n";
}
// cout<<"The shortest paths from given source "<<src<<" to\nall other nodes are,\n";
// for(int u = 0; u < n; ++u){
// if(u != src){
// cout<<"----------------------------------------\n";
// if(shortestPaths[u] < INT_MAX){
// cout<<"Path length: "<<shortestPaths[u]<<" | Path: ";
// printPath(predecessors, u);
// cout<<"\n";
// }
// else{
// cout<<"No path exits from given source "<<src<<" to "<<u<<"\n";
// }
// }
// }
}
void printGraph(){
if(!m){
cout<<"The graph is empty!!\n";
return;
}
cout<<"Total # edges in the graph: "<<m<<"\n";
for(int i = 0; i < n; ++i){
cout<<"The edges from vertex "<<i<<":";
for(auto val: adj[i])
cout<<"->"<<val;
cout<<"\n";
}
cout<<"======================================================\n";
}
void printPath(vector<int> &predecessors, int par){
if(par == -1)
return;
printPath(predecessors, predecessors[par]);
cout<<(predecessors[par] == -1 ? "":"->")<<par;
}
};
int main()
{
int n, u, v, w;
cin>>n;
Graph g(n);
cin>>n;
for(int i=0; i < n; ++i){
cin>>u>>v>>w;
g.addEdge(u,v,w);
}
g.printGraph();
g.allPairsShortestPath();
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAKY2xhc3MgR3JhcGh7CglwdWJsaWM6CglpbnQgbiwgbTsKCQoJdmVjdG9yPHZlY3RvcjxpbnQ+PiBhZGo7Cgl2ZWN0b3I8dmVjdG9yPGludD4+IFc7Cgl2ZWN0b3I8dmVjdG9yPGludD4+IHByZWRlY2Vzc29yOwogCglHcmFwaChpbnQgbm9kZXMpOiBhZGoobm9kZXMpLCBXKG5vZGVzLCB2ZWN0b3I8aW50Pihub2RlcywgSU5UX01BWCkpLCAKCQkJCQkJcHJlZGVjZXNzb3Iobm9kZXMsIHZlY3RvcjxpbnQ+KG5vZGVzLCAtMSkpewoJCW4gPSBub2RlczsKCQltID0gMDsKCQkKCQlmb3IoaW50IGk9MDsgaTxuOyArK2kpCgkJCVdbaV1baV0gPSAwOwoJfQogCgl2b2lkIGFkZEVkZ2UoaW50IHUsIGludCB2LCBpbnQgd2VpZ2h0KXsKCQlpZih1ID49IG4gfHwgdiA+PW4gfHwgdSA8IDAgfHwgdiA8IDApeyAKCQkJY291dDw8IkVpdGhlciBvZiB0aGUgdmVydGljZXMgZG9lc24ndCBleGlzdHMgaW4gdGhlIGdyYXBoLlxuIjsKCQkJcmV0dXJuOwoJCX0KIAoJCVdbdV1bdl0gPSB3ZWlnaHQ7CgkJcHJlZGVjZXNzb3JbdV1bdl0gPSB1OwogCgkJYWRqW3VdLnB1c2hfYmFjayh2KTsKIAoJCSsrbTsKCX0KIAoJdm9pZCBhbGxQYWlyc1Nob3J0ZXN0UGF0aCgpewoJCQoJCWZvcihpbnQgayA9IDA7IGsgPCBuOyArK2spewoJCQlmb3IoaW50IGkgPSAwOyBpIDwgbjsgKytpKXsKCQkJCWZvcihpbnQgaiA9IDA7IGogPCBuOyArK2opewoJCQkJCWlmKFdbaV1ba10gIT0gSU5UX01BWCAmJiBXW2tdW2pdICE9IElOVF9NQVggJiYgV1tpXVtrXSArIFdba11bal0gPCBXW2ldW2pdKXsKCQkJCQkJV1tpXVtqXSA9IFdbaV1ba10gKyBXW2tdW2pdOwoJCQkJCQlwcmVkZWNlc3NvcltpXVtqXSA9IGs7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCQoJCQkvLyBmb3IoYXV0byByb3c6IFcpewoJCQkvLyAJY291dDw8InxcdCI7CgkJCS8vIAlmb3IoYXV0byBjb2w6IHJvdyl7CgkJCS8vIAkJY291dDw8Y29sPDwiXHR8XHQiOwoJCQkvLyAJfQoJCQkvLyAJY291dDw8IlxuIjsKCQkJLy8gfQoJCQkvLyBjb3V0PDwiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIjsKCQl9CgkJCgkJY291dDw8IkZpbmFsIGRpc3RhbmNlIG1hdHJpeCh3aXRoIHJvd3MvY29scyBpbmRleGVkIFswLSI8PG4tMTw8Il0pOlxuIjsKCQlmb3IoYXV0byByb3c6IFcpewoJCQljb3V0PDwifFx0IjsKCQkJZm9yKGF1dG8gY29sOiByb3cpewoJCQkJY291dDw8Y29sPDwiXHR8XHQiOwoJCQl9CgkJCWNvdXQ8PCJcbiI7CgkJfQoJCQoJCWNvdXQ8PCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iCgkJIlByZWRlY2Vzc29yIG1hdHJpeCh3aXRoIHJvd3MvY29scyBpbmRleGVkIFswLSI8PG4tMTw8Il0pOlxuIjsKCQlmb3IoYXV0byByb3c6IHByZWRlY2Vzc29yKXsKCQkJY291dDw8InxcdCI7CgkJCWZvcihhdXRvIGNvbDogcm93KXsKCQkJCWNvdXQ8PGNvbDw8Ilx0fFx0IjsKCQkJfQoJCQljb3V0PDwiXG4iOwoJCX0JCiAKCQkvLyBjb3V0PDwiVGhlIHNob3J0ZXN0IHBhdGhzIGZyb20gZ2l2ZW4gc291cmNlICI8PHNyYzw8IiB0b1xuYWxsIG90aGVyIG5vZGVzIGFyZSxcbiI7CiAKCQkvLyAJZm9yKGludCB1ID0gMDsgdSA8IG47ICsrdSl7CgkJLy8gCQlpZih1ICE9IHNyYyl7CgkJLy8gCQkJY291dDw8Ii0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CgkJLy8gCQkJaWYoc2hvcnRlc3RQYXRoc1t1XSA8IElOVF9NQVgpewoJCS8vIAkJCQljb3V0PDwiUGF0aCBsZW5ndGg6ICI8PHNob3J0ZXN0UGF0aHNbdV08PCIgfCBQYXRoOiAiOwoJCS8vIAkJCQlwcmludFBhdGgocHJlZGVjZXNzb3JzLCB1KTsKCQkvLyAJCQkJY291dDw8IlxuIjsKCQkvLyAJCQl9CgkJLy8gCQkJZWxzZXsKCQkvLyAJCQkJY291dDw8Ik5vIHBhdGggZXhpdHMgZnJvbSBnaXZlbiBzb3VyY2UgIjw8c3JjPDwiIHRvICI8PHU8PCJcbiI7CgkJLy8gCQkJfQoJCS8vIAkJfQoJCS8vIAl9CiAKCX0KIAoJdm9pZCBwcmludEdyYXBoKCl7IAogCgkJaWYoIW0peyAKCQkJY291dDw8IlRoZSBncmFwaCBpcyBlbXB0eSEhXG4iOwoJCQlyZXR1cm47CgkJfSAKIAoJCWNvdXQ8PCJUb3RhbCAjIGVkZ2VzIGluIHRoZSBncmFwaDogIjw8bTw8IlxuIjsKIAoJCWZvcihpbnQgaSA9IDA7IGkgPCBuOyArK2kpeyAKCQkJY291dDw8IlRoZSBlZGdlcyBmcm9tIHZlcnRleCAiPDxpPDwiOiI7CiAKCQkJZm9yKGF1dG8gdmFsOiBhZGpbaV0pICAKCQkJCWNvdXQ8PCItPiI8PHZhbDsKIAoJCQljb3V0PDwiXG4iOyAKCQl9CgkJY291dDw8Ij09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIjsKCX0KIAoJdm9pZCBwcmludFBhdGgodmVjdG9yPGludD4gJnByZWRlY2Vzc29ycywgaW50IHBhcil7CgkJaWYocGFyID09IC0xKQoJCQlyZXR1cm47CiAKCQlwcmludFBhdGgocHJlZGVjZXNzb3JzLCBwcmVkZWNlc3NvcnNbcGFyXSk7CiAKCQljb3V0PDwocHJlZGVjZXNzb3JzW3Bhcl0gPT0gLTEgPyAiIjoiLT4iKTw8cGFyOwoJfQp9OwogCmludCBtYWluKCkKewoJaW50IG4sIHUsIHYsIHc7IAoJY2luPj5uOwogCglHcmFwaCBnKG4pOwogCgljaW4+Pm47CiAKCWZvcihpbnQgaT0wOyBpIDwgbjsgKytpKXsKCQljaW4+PnU+PnY+Pnc7CgkJZy5hZGRFZGdlKHUsdix3KTsKCX0KIAoJZy5wcmludEdyYXBoKCk7CiAKCWcuYWxsUGFpcnNTaG9ydGVzdFBhdGgoKTsKIAoJcmV0dXJuIDA7Cn0K