The directed weighted
graph is given. Using its weighted matrix, determine for each pair of vertices whether
there exists a shortest path between them or not.
The shortest path may not
exist for two reasons:
·
There is no way.
·
There is a way of arbitrarily small weight.
Input. The first line contains the number of vertices n (1 ≤ n ≤ 100). The next n
lines contains n numbers that
describe the weighted matrix (j-th of
the i-th row corresponds to the
weight of the edge from vertex i to
vertex j). The number 0 in this
matrix represents no edge, and any other number – the existence of an edge of
corresponding weight. All the numbers do not exceed 100 by absolute value.
Output. Print n
rows with n numbers: the j-th number in the i-th row must be 0 if the path from i to j does not exist, 1
if there is a shortest path, and 2 if there is a path of arbitrarily small
weight.
Sample
input |
Sample
output |
5 0 1 2 0 0 1 0 3 0 0 2 3 0 0 0 0 0 0 0 -1 0 0 0 -1 0 |
1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 2 2 0 0 0 2 2 |
graphs – Floyd-Warshall
algorithm
Algorithm analysis
Apply the Floyd-Warshall algorithm to the input
graph. A path between the vertices i and j does not exist, if
at the completion of algorithm m[i][j] = +∞. The shortest path between
nodes i and j does not exist, if there is a node k such that there exist the paths of any length from i to k
and from k to j, and between k and k the cycle of negative length exists
(m[k][k] < 0).
In
all other cases the path between i and
j exists.
Example
Graph given in a sample,
has a form:
Algorithm realization
Store the adjacency matrix
in array m. We shall build the resulting matrix in array res. Let the value
“plus infinity” equals to INF.
#define INF 0x3F3F3F3F
#define MAX 101
int m[MAX][MAX], res[MAX][MAX];
The Floyd-Warshall algorithm.
As the graph vertices have negative weights, process them carefully: if at some
stage of processing m[i][j] becomes less than -INF, set m[i][j]
= -INF.
void floyd(void)
{
for(int k = 0; k < n; k++)
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if
((m[i][k] < INF) && (m[k][j] < INF))
{
if
(m[i][k] + m[k][j] < m[i][j]) m[i][j] = m[i][k] + m[k][j];
if
(m[i][j] < -INF) m[i][j] = -INF;
}
}
The main part of the program. Read the input adjacency
matrix. Set zeroes on its diagonal. If there is no edge between vertices i and j, set m[i][j] = INF.
scanf("%d",&n);
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
{
scanf("%d",&m[i][j]);
if ((m[i][j]
== 0) && (i != j)) m[i][j] = INF;
}
Run the Floyd-Warshall algorithm.
floyd();
Build the resulting matrix res. If there is no path
between vertices i and j, set res[i][j] = 0. Otherwise set res[i][j]
= 1, after which look for the cycle paths.
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
{
if (m[i][j]
== INF) res[i][j] = 0; else
{
res[i][j] = 1;
The shortest path does not exist between the vertices i and j if for some vertex k there
exist a path from i to k and from k to j, and also exists a
cycle of negative length that starts and finishes at vertex k (then m[k][k] < 0).
for(k = 0;
k < n; k++)
if
((m[k][k] < 0) && (m[i][k] < INF) && (m[k][j] < INF))
res[i][k] = res[i][j] = res[k][j] = 2;
}
}
Print the resulting matrix res.
for(i = 0; i < n; i++)
{
for(j = 0; j
< n; j++)
printf("%d ",res[i][j]);
printf("\n");
}
Java realization
import java.util.Scanner;
public class Main
{
static final int INF =
100000000;
static int m[][],
res[][];
static int n;
static void floyd()
{
for(int k = 0;
k < n; k++)
for(int i = 0;
i < n; i++)
for(int j = 0;
j < n; j++)
if ((m[i][k]
< INF) && (m[k][j]
< INF))
{
if (m[i][k] + m[k][j]
< m[i][j]) m[i][j] = m[i][k] + m[k][j];
if (m[i][j]
< -INF) m[i][j] = -INF;
}
}
public static void
main(String[] args)
{
Scanner con = new
Scanner(System.in);
n = con.nextInt();
m = new int[n][n];
res = new int[n][n];
for(int i = 0;
i < n; i++)
for(int j = 0;
j < n; j++)
{
m[i][j] = con.nextInt();
if ((m[i][j] ==
0) && (i != j)) m[i][j] = INF;
}
floyd();
for(int i = 0;
i < n; i++)
for(int j = 0;
j < n; j++)
{
if (m[i][j] == INF) res[i][j] =
0; else
{
res[i][j] =
1;
for(int k = 0;
k < n; k++)
if ((m[k][k]
< 0) && (m[i][k]
< INF) && (m[k][j]
< INF)) res[i][k] = res[i][j] = res[k][j] =
2;
}
}
for(int i = 0;
i < n; i++)
{
for(int j = 0;
j < n; j++)
System.out.print(res[i][j] + "
");
System.out.println();
}
con.close();
}
}