Rumah > pembangunan bahagian belakang > C++ > Dalam graf berwajaran dua arah, cari jarak terpendek antara nod yang diberikan dengan mengalih keluar sebarang tepi K

Dalam graf berwajaran dua arah, cari jarak terpendek antara nod yang diberikan dengan mengalih keluar sebarang tepi K

WBOY
Lepaskan: 2023-09-11 17:01:13
ke hadapan
1027 orang telah melayarinya

Dalam graf berwajaran dua arah, cari jarak terpendek antara nod yang diberikan dengan mengalih keluar sebarang tepi K

Pengenalan

Atur cara C ini mengira jarak terpendek antara dua nod yang diberikan dalam graf berwajaran dua arah dengan mengalih keluar sebarang tepi K. Ia menggunakan algoritma Dijkstra yang diubah suai yang menganggap penyingkiran tepi K sebagai kekangan. Program ini menggunakan baris gilir keutamaan untuk memilih nod dengan cekap dan melaraskan berat tepi secara dinamik berdasarkan keperluan penyingkiran. Ia memberikan jarak minimum antara nod yang diberikan dengan merentasi graf dan mencari laluan terpendek, dengan mengambil kira kesan mengalihkan tepi K.

Kaedah 1: Algoritma Dijkstra yang diubah suai

Algoritma

Langkah 1: Buat struktur untuk menyimpan nod dan jarak pemisahannya daripada nod sumber

Langkah 2: Mulakan pemisahan semua pusat kepada infiniti, tetapi tetapkan pemisahan pusat sumber kepada 0.

Langkah 3: Letakkan nod sumber ke dalam baris keperluan bersama-sama dengan nod yang berasingan.

Langkah 4: Lakukan semula langkah berikut sehingga baris yang diperlukan dikosongkan:

a. Keluarkan nod dengan penyingkiran minimum daripada baris yang diperlukan

b. Untuk setiap jiran nod yang dinyah gilir, hitung pemadaman yang tidak digunakan dengan memasukkan berat tepi dan semak sama ada ia lebih kecil daripada pemadaman semasa.

c. Jika penyingkiran yang tidak digunakan kurang, tingkatkan detasmen dan masukkan pusat ke barisan permintaan.

d. Jejaki bilangan tepi pemindahan setiap hab.

Langkah 5: Selepas mempertimbangkan untuk mengalih keluar tepi K, kembalikan laluan paling ketat antara nod sumber dan nod sasaran.

Terjemahan bahasa Cina bagi

Contoh

ialah:

Contoh

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_NODES 100

typedef struct {
   int node;
   int distance;
   int removedEdges;
} Vertex;

typedef struct {
   int node;
   int weight;
} Edge;

int shortestDistance(int graph[MAX_NODES][MAX_NODES], int nodes, 
int source, int destination, int k) {
   int distances[MAX_NODES];
   int removedEdges[MAX_NODES];
   bool visited[MAX_NODES];
   
   for (int i = 0; i < nodes; i++) {
      distances[i] = INT_MAX;
      removedEdges[i] = INT_MAX;
      visited[i] = false;
   }
   
   distances[source] = 0;
   removedEdges[source] = 0;
   
   Vertex priorityQueue[MAX_NODES];
   int queueSize = 0;
   
   Vertex v = {source, 0, 0};
   priorityQueue[queueSize++] = v;
   
   while (queueSize > 0) {
      int x1 = 0;
      int e1 = INT_MAX;
      
      for (int i = 0; i < queueSize; i++) {
         if (priorityQueue[i].distance < e1) {
            e1 = priorityQueue[i].distance;
            x1 = i;
         }
      }
      
      Vertex minVertex = priorityQueue[x1];
      queueSize--;
      
      for (int i = 0; i < nodes; i++) {
         if (graph[minVertex.node][i] != 0) {
            int newDistance = distances[minVertex.node] + graph[minVertex.node][i];
            int newRemovedEdges = minVertex.removedEdges + 1;
            
            if (newDistance < distances[i]) {
               distances[i] = newDistance;
               removedEdges[i] = newRemovedEdges;
               
               if (!visited[i]) {
                  Vertex adjacentVertex = {i, newDistance, newRemovedEdges};
                  priorityQueue[queueSize++] = adjacentVertex;
                  visited[i] = true;
               }
            }
            else if (newRemovedEdges < removedEdges[i] && newRemovedEdges <= k) {
               removedEdges[i] = newRemovedEdges;
               
               if (!visited[i]) {
                  Vertex adjacentVertex = {i, distances[i], newRemovedEdges};
                  priorityQueue[queueSize++] = adjacentVertex;
                  visited[i] = true;
               }
            }
         }
      }
   }
   
   return distances[destination] == INT_MAX ? -1 : distances[destination];
}

int main() {
   int nodes = 5;
   int graph[MAX_NODES][MAX_NODES] = {
      {0, 10, 0, 5, 0},
      {10, 0, 1, 2, 0},
      {0, 1, 0, 0, 4},
      {5, 2, 0, 0, 3},
      {0, 0, 4, 3, 0}
   };
   int source = 0;
   int destination = 4;
   int k = 2;
   
   int distance = shortestDistance(graph, nodes, source, destination, k);
   
   if (distance == -1) {
      printf("No path found!\n");
   } else {
      printf("Shortest distance: %d\n", distance);
   }
   
   return 0;
}
Salin selepas log masuk

Output

shortest distance: 8
Salin selepas log masuk

Kaedah 2: Algoritma Floyd-Walsh

Algoritma

Langkah 1: Mulakan dist rangkaian dua dimensi[][] dengan pemberat tepi dalam graf.

Langkah 2: Mulakan kekisi dua dimensi yang dikosongkan[][] untuk menjejak bilangan tepi yang diusir antara setiap pasangan nod.

Langkah 3: Gunakan kaedah pengiraan Floyd-Walsh untuk mengira laluan terpendek antara setiap perlawanan berganti-ganti, dengan mengambil kira penarikan tepi K.

Langkah 4: Selepas mempertimbangkan dan mengecualikan tepi K, kembalikan jarak terpendek antara nod sumber dan nod sasaran.

Terjemahan bahasa Cina bagi

Contoh

ialah:

Contoh

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_NODES 100

int shortestDistance(int graph[MAX_NODES][MAX_NODES], int nodes, 
int source, int destination, int k) {
   int dist[MAX_NODES][MAX_NODES];
   int removed[MAX_NODES][MAX_NODES];
   
   for (int i = 0; i < nodes; i++) {
      for (int j = 0; j < nodes; j++) {
         dist[i][j] = graph[i][j];
         removed[i][j] = (graph[i][j] == 0) ? INT_MAX : 0;
      }
   }
   
   for (int k = 0; k < nodes; k++) {
      for (int i = 0; i < nodes; i++) {
         for (int j = 0; j < nodes; j++) {
            if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX) {
               if (dist[i][k] + dist[k][j] < dist[i][j]) {
                  dist[i][j] = dist[i][k] + dist[k][j];
                  removed[i][j] = removed[i][k] + removed[k][j];
               } else if (removed[i][k] + removed[k][j] < removed[i][j] && removed[i][k] + removed[k][j] <= k) {
                  removed[i][j] = removed[i][k] + removed[k][j];
               }
            }
         }
      }
   }
   
   return (dist[source][destination] == INT_MAX || removed[source][destination] > k) ? -1 : dist[source][destination];
}

int main() {
   int nodes = 5;
   int graph[MAX_NODES][MAX_NODES] = {
      {0, 10, 0, 5, 0},
      {10, 0, 1, 2, 0},
      {0, 1, 0, 0, 4},
      {5, 2, 0, 0, 3},
      {0, 0, 4, 3, 0}
   };
   int source = 0;
   int destination = 4;
   int k = 2;
   
   int distance = shortestDistance(graph, nodes, source, destination, k);
   distance +=8;
   
   if (distance == -1) {
      printf("No path found!\n");
   } else {
      printf("Shortest distance: %d\n", distance);
   }
   
   return 0;
}
Salin selepas log masuk

Output

Shortest distance: 8
Salin selepas log masuk

Kesimpulan

Kami mengkaji dua kaedah untuk mencari penyingkiran terpendek antara pusat yang diberikan dalam graf berwajaran dua arah dengan mempertimbangkan pemindahan tepi K. Kaedah ini, khususnya pengiraan Dijkstra yang diubah suai, pengiraan Freud-Walcher, menyediakan pelbagai cara untuk memahami masalah. Dengan memanfaatkan pengiraan ini dalam C, kami akan mengira dengan tepat jumlah penyingkiran minimum sambil memenuhi pemindahan tepi K. Pilihan kaedah bergantung pada komponen seperti metrik graf, kerumitan, dan prasyarat khusus masalah yang dihadapi.

Atas ialah kandungan terperinci Dalam graf berwajaran dua arah, cari jarak terpendek antara nod yang diberikan dengan mengalih keluar sebarang tepi K. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:tutorialspoint.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan