/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

// C Program for Floyd Warshall Algorithm
#include<iostream>
using namespace std;
typedef enum {z,les,leq,que,na} relation;
// Number of vertices in the graph
//#define V 4
relation addition[4][4] = {{les,les,que,les},{les,leq,que,leq},{que,que,que,que},{les,leq,que,na}};
string sarr[4] = {"<","<=","?","NA"};
/* Define Infinite as a large enough value. This value will be used
for vertices not connected to each other */
//#define INF na

// A function to print the solution matrix
void printSolution(relation dist[][], int V);

// Solves the all-pairs shortest path problem using Floyd Warshall algorithm
void floydWarshall (relation graph[][], int V)
{
	/* dist[][] will be the output matrix that will finally have the shortest 
	distances between every pair of vertices */
	relation dist[V][V];
	int i, j, k;

	/* Initialize the solution matrix same as input graph matrix. Or 
	we can say the initial values of shortest distances are based
	on shortest paths considering no intermediate vertex. */
	for (i = 0; i < V; i++)
		for (j = 0; j < V; j++)
			dist[i][j] = graph[i][j];

	/* Add all vertices one by one to the set of intermediate vertices.
	---> Before start of a iteration, we have shortest distances between all
	pairs of vertices such that the shortest distances consider only the
	vertices in set {0, 1, 2, .. k-1} as intermediate vertices.
	----> After the end of a iteration, vertex no. k is added to the set of
	intermediate vertices and the set becomes {0, 1, 2, .. k} */
	for (k = 0; k < V; k++)
	{
		// Pick all vertices as source one by one
		for (i = 0; i < V; i++)
		{
			// Pick all vertices as destination for the
			// above picked source
			for (j = 0; j < V; j++)
			{
				// If vertex k is on the shortest path from
				// i to j, then update the value of dist[i][j]
				relation m = addition[dist[i][k]][dist[k][j]];
				if (m < dist[i][j])
					dist[i][j] = m;
			}
		}
	}

	// Print the shortest distance matrix
	printSolution(dist);
}

/* A utility function to print solution */
void printSolution(relation dist[][],int V)
{
	cout << "Following matrix shows the shortest distances" << 
			" between every pair of vertices" << endl;
	cout.width(7);
	for (int i = 0; i < V; i++)
	{
		for (int j = 0; j < V; j++)
		{
			cout << sarr[dist[i][j]];
		}
		cout << endl;
	}
}

// driver program to test above function
int main()
{
	/* Let us create the following weighted graph
			10
	(0)------->(3)
		|		 /|\
	5 |		 |
		|		 | 1
	\|/		 |
	(1)------->(2)
			3		 */
	relation graph[V][V] = { {z,que,les,na},
						{na,z,na,leq},
						{na,les,z,na},
						{leq,na,na,z}
					};

	// Print the solution
	floydWarshall(graph);
	return 0;
}
