Vamos lá.
-
Implementar um grafo usando matriz de adjacências vai implicar em algumas coisas. a) não poderá haver mais de uma aresta entre dois vértices; b) o tratamento de laços, ou seja, uma aresta de um vértice a ele mesmo, tem que ser diferenciado. Essa característica é considerada como uma “anomalia” e normalmente não precisa ser representada dada a natureza do que você está representando com o grafo; c) caso seu grafo seja esparso, ou seja, a relação entre vértices e arestas seja baixa, vai haver desperdício de tempo para encontrar os vértices adjacentes, chegando aqui na sua pergunta. Em uma matriz de adjacências, cada coluna ou linha da matriz conterá a ligação entre dois vértices, sendo assim, basta iterar pela linha ou coluna do vértice desejado e ir verificando em quais vértices há ligação. Pela natureza do seu problema, você está implementando um grafo ponderado, então o que há na sua matriz é o peso entre dois vértices. É isso?
-
Você quer o menor caminho, certo? O algoritmo base é o da busca em largura, que tem que ser “melhorado” para calcular os menores caminhos entre os vértices. Um algoritmo é o de Dijkstra que você comentou que resolve esse problema para arestas com valores positivos. Se precisar lidar com valores negativos, você terá que usar o algoritmo de Bellman-Ford.
Sinceramente, recomendo que primeiro você entenda o que é um grafo, quais suas características e propriedades. Estude como implementar, pois há várias maneiras, com prós e contras: lista de arestas, matriz de adjacências, lista de adjacências, chave-valor, encadeamento… Estude também os digrafos (lê-se di-grafos, sem tonicidade na primeira sílaba).
Depois disso, estude os algoritmos fundamentais: Busca em profundidade (Depth-first Search), Busca em largura (Breadth-first Search), Components Conexos (Connected Components) e algoritmos de extração de propriedades, como grau dos vértices, etc.
Então, depois de tudo isso, estude os algoritmos de menor caminho (Dijkstra) e os de árvores geradoras mínimas (minimum spanning trees) os principais são a) Prim-Jarnik; b) Kruskal e c) Boruvka.
Aí sim, sabendo como as coisas funcionam de verdade, instancie seu problema. De bate pronto não me parece que seu problema é polinomial, dado a essa característica de levar em consideração as cidades dos amigos… Provavelmente você precisará computar isso com alguma técnica de otimização.
Enfim, vc tem bastante coisa para fazer. Há bastante bibliografia. Eu recomendo, para começar, o livro Algorithms (https://algs4.cs.princeton.edu/home/). Para mim é um dos melhores, senão o melhor, livro sobre algoritmos e estruturas de dados essenciais.