Преобразовать матрицу с++
У меня есть матрица, которая показывает из какой вершины можно попасть в какую. Так же будем считать, что из i-ой вершины можно попасть в i-ю вершину.Матрица на входе (жирным выделены № вершин):
n 1 2 3 4 5 6 7 8 9 10
1 1 0 0 1 0 0 1 0 0 1
2 0 1 1 1 1 0 1 0 0 1
3 0 0 1 0 0 0 0 1 1 0
4 0 0 0 1 1 0 0 0 0 0
5 0 0 0 0 1 0 0 1 1 0
6 0 0 0 0 0 1 0 0 0 1
7 0 0 0 0 0 0 1 0 0 1
8 0 0 0 0 0 0 0 1 1 0
9 0 0 0 0 0 0 0 0 1 1
Я пытаюсь построить матрицу, которая будет показывать все пути из каждой точки, например:
первый путь будет таким: 1->4->5->8->9->10
(т.е. мы из пункта 1 переходим в пункт 4, из 4 ближайший пункт 5, в 5-ом ближайший 8 и т. д).
второй: 1->7->10
поскольку из 1 в 4 мы уже ходили, идём из 1 в 7, а из 7 сразу в 10)
и так по порядку, сначала смотрим все пути с началом в пункте 1, потом с началом в пункте 2 и.д.
Это должно будет превратиться в такую матрицу:
1 0 0 1 1 0 0 1 1 1
1 0 0 0 0 0 1 0 0 1
. . . . . . . . . . . . . . . .
0 1 1 0 0 0 0 1 1 1
. . . . . . . . . . . . . . . .
0 0 0 0 0 0 0 0 1 1
Мой алгоритм действий: Ищем в строке первую единицу кроме начальной (потому что это точка отправления), приравниваем её к 0 и переходим на строчку под её номером, т.е., если a[j-столбец][i-строка] == 1, переходим на a[i][i] и так дальше.
Если совсем грубо, выглядит это примерно так:
//выше будет цикл, который будет обнулять z для того, чтобы каждый раз возвращаться к началу матрицы
for (int j = z; j < n; j++) {
for (int i = j+1; i < m; i++) {//i=j+1, чтобы не считать первую единицу строки
cout << matrix[j][i] << " ";
if (matrix[j][i] == 1){ //Если элемент матрицы равен 1, то..
if(ty==0) //ty нужен для того, чтобы удалить только первую встречную 1, т.к. если удалять все 1 будут проблемы
matrix[j][i] = 0; //приравниваем эту единицу к 0
ty = 1; // теперь ty = 1 и мы не будем в этой итерации больше приравнивать значения к 0
j = i; //Теперь j=i , т.е. если мы нашли, что значение 1 было на 5 пункте то переходим на 5 строку
break;
}
}
}
Надеюсь смысл уловить можно. Прошу посоветовать, как лучше поправить код. После двух-летнего перерыва тяжело возвращаться к с++ :(
UPD: поправил код, стало лучше, но всё равно ещё не то
for(int x=0;x<20;x++){ //поставил х = 20, чтобы не было слишком много строк
ty = 0; // принимает значения 0/1, если 0, то мы, ещё не нашли первую вершину равную 1, не считая изначальной
for (int j = 0; j < n; j++) {
for (int i = j+1; i < m; i++) { //i = j+1 для того, чтобы не считать изначальную
if (matrix[j][i - 1] == 1 && ty == 0) {
cout << " |1| "; //для наглядности, показывает начальную вершину
}
cout << matrix[j][i] << " ";
if (matrix[j][i] == 1){
if (ty == 0) {
matrix[j][i] = 0; //приравниваем первую найденную 1 к 0, чтобы не повторяться
ty = 1; //приравниваем оператор к 1, только как мы закончим с первой строкой новой матрицы, обнулим это значение
}
cout << "|" << j+1 << i+1 << "| "; //показываем координаты вершины, которая равна 1 (начинаем не с 0, а с 1)
j = i-1;
break;
}
cout << matrix[j][i] << " ";
}
}
cout << endl;
}
Проблема в том, что дублируются первые строки.
Код с результатом тут:
http://cpp.sh/9sypz
UPD2:Опишу точнее:
1->4->5->8->9->10
1->7->10
1->10
из первого пункта мы перебрали все пути, теперь смотрим из второго
2->3->8->9->10
2->4->5->8->9->10
2->5->8->9->10
2->7->10
2->10
из 2 пункта тоже всё перебрали
3->8->9->10
и т. д.
В матричном виде это будет выглядеть так:
1 0 0 1 1 0 0 1 1 1
1 0 0 0 0 0 1 0 0 1
1 0 0 0 0 0 0 0 0 1
0 1 1 0 0 0 0 1 1 1
0 1 0 1 1 0 0 1 1 1
0 1 0 0 0 0 1 0 0 1
0 1 0 0 0 0 0 0 0 1
0 0 1 0 0 0 0 1 1 1
UPD3: Решил протестировать с выводом, вместо матрицы я вывожу пути, и можно заметить, что алгоритм работает, только я никак не могу сообразить это грамотно перевести в матрицу http://cpp.sh/25yme