0-1 qrafı quraq: mövcud tillərə çəkisini, onların əks tillərinə isə çəkisini verək. Sonra enliliyinə axtarış (BFS) işə salaq. təpəsindən təpəsinə ən qısa yolun uzunluğu tərs çevrilməli olan tillərin minimal sayına bərabər olacaqdır.
Nümunə
Nümunədə verilmiş qraf aşağıdakı kimidir:
Alqoritmin realizasiyası
Sonsuzluq sabitini elan edək.
#define INF 0x3F3F3F3FƏn qısa məsafələr massivi -i və qrafın qonşuluq siyahısı -ni elan edək. Hər til üçün qonşu təpə ilə birlikdə tilin çəkisini ( və ya ) saxlayırıq.
vector\<int\> dist;
vector\<vector\<pair\<int, int\> \> \> g;bfs funksiyası təpəsindən enliliyinə axtarışı realizasiya edir.
void bfs(int start)
{
dist = vector\<int\>(n + 1, INF);
dist[start] = 0;
deque\<int\> q;
q.push_back(start);
while (!q.empty())
{
int v = q.front(); q.pop_front();
for (auto edge : g[v])
{
int to = edge.first;
int w = edge.second;
if (dist[to] \> dist[v] + w)
{
dist[to] = dist[v] + w;Tilin çəkisindən asılı olaraq təpəsini növbənin sonuna və ya əvvəlinə əlavə edirik.
if (w == 1)
q.push_back(to);
else
q.push_front(to);
}
}
}
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyuruq.
scanf("%d %d", \&n, \&m);
g.resize(n + 1);
for (i = 0; i \< m; i++)
{
scanf("%d %d", \&a, \&b);Yönəldilmiş a → b tilinə çəkisini, əks tilə isə çəkisini veririk.
g[a].push_back({ b, 0 });
g[b].push_back({ a, 1 });
}təpəsindən enliliyinə axtarışı işə salırıq.
bfs(1);Cavabı — təpəsinə qədər olan ən qısa məsafəni çap edirik.
if (dist[n] == INF)
printf("-1\n");
else
printf("%d\n", dist[n]);