-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLab04.cs
More file actions
106 lines (93 loc) · 4.06 KB
/
Copy pathLab04.cs
File metadata and controls
106 lines (93 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using ASD.Graphs;
using System;
using System.Collections.Generic;
namespace ASD
{
public class Lab04 : MarshalByRefObject
{
/// <summary>
/// Etap 1 - Szukanie mozliwych do odwiedzenia miast z grafu skierowanego
/// przy zalozeniu, ze pociagi odjezdzaja co godzine.
/// </summary>
/// <param name="graph">Graf skierowany przedstawiający siatke pociagow</param>
/// <param name="miastoStartowe">Numer miasta z ktorego zaczyna sie podroz pociagiem</param>
/// <param name="K">Godzina o ktorej musi zakonczyc sie nasza podroz</param>
/// <returns>Tablica numerow miast ktore mozna odwiedzic. Posortowana rosnaco.</returns>
public int[] Lab04Stage1(DiGraph graph, int miastoStartowe, int K)
{
bool[] visited = new bool[graph.VertexCount];
var q = new Queue<int>();
q.Enqueue(miastoStartowe);
visited[miastoStartowe] = true;
// Wykonujemy BFS'a tak głęboko, ile mamy godzin na jazdę
for (int i = 8; i < K; i++)
{
// Należy zapamiętać ile było elementów w kolejce na tej głębokości, będą dochodzić w trakcie kolejne
for (int t = q.Count; t > 0; t--)
{
int v = q.Dequeue();
foreach (int u in graph.OutNeighbors(v))
{
if (!visited[u])
{
q.Enqueue(u);
visited[u] = true;
}
}
}
}
// Możliwe do odwiedzenia miasta. Przy okazji spełniamy warunek sortowania rosnącego
var cities = new List<int>();
for (int i = 0; i < graph.VertexCount; i++)
{
if (visited[i])
cities.Add(i);
}
return cities.ToArray();
}
/// <summary>
/// Etap 2 - Szukanie mozliwych do odwiedzenia miast z grafu skierowanego.
/// Waga krawedzi oznacza, ze pociag rusza o tej godzinie
/// </summary>
/// <param name="graph">Wazony graf skierowany przedstawiający siatke pociagow</param>
/// <param name="miastoStartowe">Numer miasta z ktorego zaczyna sie podroz pociagiem</param>
/// <param name="K">Godzina o ktorej musi zakonczyc sie nasza podroz</param>
/// <returns>Tablica numerow miast ktore mozna odwiedzic. Posortowana rosnaco.</returns>
public int[] Lab04Stage2(DiGraph<int> graph, int miastoStartowe, int K)
{
int[] visitedAt = new int[graph.VertexCount];
for (int i = 0; i < graph.VertexCount; i++)
visitedAt[i] = int.MaxValue;
var q = new PriorityQueue<int, (int, int)>();
q.Insert((miastoStartowe, 8), 8);
visitedAt[miastoStartowe] = 8;
// Dijkstra
while (q.Count > 0)
{
(int v, int hour) = q.Extract();
// Znaleziono już lepszą trasę, niż ta znajdująca się jeszcze w kolejce
if (hour > visitedAt[v])
continue;
foreach (var e in graph.OutEdges(v))
{
int arrival = e.Weight + 1;
// Odjazd później && Dojazd w czasie && Będziemy tam szybciej niż dotychczas
if (e.Weight >= hour && arrival <= K && arrival < visitedAt[e.To])
{
// Nie ma sensu dodawać, jak nigdzie stamtąd nie pojedziemy
if (arrival != K)
q.Insert((e.To, arrival), arrival);
visitedAt[e.To] = arrival;
}
}
}
var cities = new List<int>();
for (int i = 0; i < graph.VertexCount; i++)
{
if (visitedAt[i] != int.MaxValue)
cities.Add(i);
}
return cities.ToArray();
}
}
}