Gəlin, qaynaq təpə və təyinat vertex -dən başlayaraq genişliyinə birinci axtarış həyata keçirək. massivində -dən olan ən qısa məsafələri və massivində -dən olan ən qısa məsafələri saxlayın.
Qeyd: optDistance və arasında olan qısadır.
İndi, və düyünlər arasında yeni bir yol tikmə imkanını nəzərdən keçirək.
Qrafa yolunu əlavə etdikdə, yeni yollar yaradılır:
Əgər bu məsafələrdən hər hansı biri optDistance-dən kiçikdirsə, bu halda yolunun əlavə edilməsi və arasında olan ən qısa məsafənin azalmasına səbəb olacaq və buna görə də uyğundur.
İndi bütün mümkün cütləri yoxlamaq və yeni bir yolun əlavə edilməsi və arasında olan ən qısa məsafəni azaldıb-azaltmayacağını təsdiq etməliyik.
Misal
Birinci testin qrafi solda göstərilib. Tepə -dən təpə -ə olan ən qısa məsafə -dür. Hansı yeni yolu əlavə etsək də, bu məsafə azalacaq. Buna görə də tələb olunan yollar mövcud deyil.
İkinci testin qrafi sağda göstərilib. Tepə -dən tepe -ə ən qısa məsafə -dir. Mümkün yeni yollar qalın xətlərlə işarələnmişdir. Bu yollardan hansını seçməyimizdən asılı olmayaraq, və arasındakı məsafə azalmayacaqdır.
Alqoritm tətbiqi
sabitini müəyyənləşdirin — qrafa mümkün olan ən çox sayda vertex.
#define MAX 1001Əlaqə matrisini və ən qısa məsafələr üçün massivləri bəyan edin.
int g[MAX][MAX], distS[MAX], distF[MAX];bfs funksiyası vertexdən -da genişliyinə birinci axtarışı yerinə yetirir. Ən qısa məsafələrin saxlanılacağı massivini qəbul edir.
void bfs(int start, int *dist)
{Ən qısa məsafələrin massivi -i başladın.
for (int i = 0; i <= n; i++) dist[i] = -1;
dist[start] = 0;Bir sıra bəyan edin və başlayaq vertex -ı oraya əlavə edin.
queue<int> q;
q.push(start);Növbədə vertex boş olmayana qədər çıxarın.
while (!q.empty())
{
int v = q.front(); q.pop();Bütün vertexlər -u -yə bitişik olaraq keçirin. Əgər vertexi hələ ziyarət edilməyibsə, ən qısa məsafəni dist[to] hesablayın və onu növbəyə əlavə edin.
for (int to = 1; to <= n; to++)
if (g[v][to] && dist[to] == -1)
{
q.push(to);
dist[to] = dist[v] + 1;
}
}
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyun.
scanf("%d %d %d %d", &n, &m, &s, &f);
memset(g, 0, sizeof(g));Yönsüz qrafı oxuyun.
for (i = 0; i < m; i++)
{
scanf("%d %d", &a, &b);
g[a][b] = g[b][a] = 1;
}Tepələrdən və -dən genişliyinə birinci axtarışı həyata keçirin. Ən qısa məsafələr və massivlərinə saxlanılır.
bfs(s, distS);
bfs(f, distF);Qeyd edək ki, optDistance orijinal qrafda və arasındakı ən qısa məsafədir.
optDistance = distS[f];Bütün vertex cütlərini və boyunca keçirin və aralarında yeni bir yol tikmə imkanını nəzərdən keçirin. dəyişəni bu cür uyğun yolların sayını izləyir.
res = 0;
for (i = 1; i <= n; i++)
for (j = i + 1; j <= n; j++)Əgər və vertexlər arasında heç bir yol yoxdursa, s → i → j → f və s → j → i → f ən qısa yolların uzunluğunu hesablayın. Əgər bu məsafələrin hər ikisi optDistance-dən az deyilsə, onda bu cür yol tikilməlidir.
if (g[i][j] == 0)
{
if ((distS[i] + distF[j] + 1 >= optDistance) &&
(distS[j] + distF[i] + 1 >= optDistance))
res++;
}Cavabı çap edin.
printf("%d\n", res);Java tətbiqi
import java.util.*;
public class Main
{
static int g[][], distS[], distF[];
static int n, m, s, f;
static void bfs(int start, int dist[])
{
Arrays.fill(dist,-1);
dist[start] = 0;
Queue<Integer> q = new LinkedList<Integer>();
q.add(start);
while(!q.isEmpty())
{
int v = q.poll();
for (int to = 1; to <= n; to++)
if (g[v][to] == 1 && dist[to] == -1)
{
q.add(to);
dist[to] = dist[v] + 1;
}
}
}
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
n = con.nextInt();
m = con.nextInt();
s = con.nextInt();
f = con.nextInt();
g = new int[n+1][n+1];
distS = new int[n+1];
distF = new int[n+1];
for (int i = 1; i <= m; i++)
{
int a = con.nextInt();
int b = con.nextInt();
g[a][b] = g[b][a] = 1;
}
bfs(s, distS);
bfs(f, distF);
int optDistance = distS[f];
int res = 0;
for(int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
if (g[i][j] == 0)
{
if ((distS[i] + distF[j] + 1 >= optDistance) &&
(distS[j] + distF[i] + 1 >= optDistance))
res++;
}
System.out.println(res);
con.close();
}
}