Andrzej Jastrz bski Akademia ET I
Graf Grafem nazywamy par G = (V, E), gdzie V to zbiór wierzchoªków, E zbiór kraw dzi taki,»e E {{u, v} : u, v V u v}. Wierzchoªki v, u V s s siaduj ce je±li s poª czone kraw dzi ( e E {v, u} = e). Wierzchoªek v V jest incydentny do kraw dzi e E je±li v jest jednym z ko«ców e (v e). Kraw dzie e, f E s s siaduj ce je±li s incydentne do tego samego wierzchoªka ( v V v e u f ). mo»na reprezentowa na pªaszczy¹nie jako kropki (wierzchoªki) i linie pomi dzy kropkami (kraw dzie).
Reprezentacja grafu S dwie podstawowe metody reprezentacji grafu: macierz s siedztwa listy s siedztwa Modykacj list s siedztwa jest reprezentacja przez p ki wyj±ciowe.
reprezentacja graczna 1 2 3 1 2 3 listy s siedztwa 3 3 2 1 1 3 p ki wyj±ciowe macierz s siedztwa 0 0 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 2 3 3 3 2 1 1 3? 0 1 2 3 0 1 2 3
Macierz s siedztwa Macierz s siedztwa, to macierz kwadratowa o rozmiarze V V wypeªniona liczbami 0 i 1. Ponumerujmy wierzchoªki od 1 do V. W i-tej kolumnie i j-tym wierszu jest liczba 1 wtedy i tylko wtedy, gdy wierzchoªek i-ty jest s siedni z wierzchoªkiem j-tym.
Przykªady We wszystkich przykªadach b dziemy zakªadali,»e graf do programu jest w podany ni»ej sposób. Najpierw podane s dwie liczby n liczba wierzchoªków i m liczba kraw dzi. Nast pnie podanych jest m par liczb opisuj cych s siednie wierzchoªki. Wierzchoªki liczymy od 0. 3 3 0 1 1 2 2 0
Czytanie grafu - macierz s siedztwa int main() { int **G; int n, m, v, u; cin >> n >> m; G = new int*[n]; //tworzenie dwuwymiarowej tablicy for(int i=0; i<n; i++) { G[i] = new int[n]; for(int j=0; j<n; j++) G[i][j] = 0; } for(int i=0; i<m; i++) { cin >> v >> u; //czytanie s siadów G[u][v] = G[v][u] = 1; }. //dowolny algorytm for(int i=0; i<n; i++) delete [] G[i]; //kasowanie delete [] G; return 0; }
Czytanie grafu - macierz s siedztwa w STLu int main() { vector< vector<int> > G; int n, m, v, u; cin >> n >> m; G.resize(n); //tworzenie dwuwymiarowej tablicy for(int i=0; i<n; i++) { G[i].resize(n); for(int j=0; j<n; j++) G[i][j] = 0; } for(int i=0; i<m; i++) { cin >> v >> u; //czytanie s siadów G[u][v] = G[v][u] = 1; }. //dowolny algorytm //kasowanie odbywa si automatycznie return 0; }
Czytanie grafu - listy s siedztwa struct Node { int v; Node *next; }; int main() { Node **G, *tmp; int n, m, v, u; cin >> n >> m; G = new Node*[n]; //tworzenie punktu wej±cia do list for(int i=0; i<n; i++) G[i] = NULL; //zerowanie for(int i=0; i<m; i++) { cin >> u >> v; tmp = new Node; //tworzenie s siada wierzchoªka v tmp->v = u; tmp->next = G[v]; G[v] = tmp; tmp = new Node; //tworzenie s siada wierzchoªka u tmp->v = v; tmp->next = G[u]; G[u] = tmp; }. //dowolny algorytm
Czytanie grafu - listy s siedztwa cd. }. for(int i=0; i<n; i++) {//kasowanie list Node *del = G[i]; while(del!=null) { tmp = del->next; delete del; del = tmp; } } delete [] G;
Czytanie grafu - listy s siedztwa w STLu int main() { vector< list<int> > G; int n, m, v, u; cin >> n >> m; G.resize(n); //tworzenie punktu wej±cia do list for(int i=0; i<m; i++) { cin >> u >> v; G[u].push_back(v); G[v].push_back(u); }. //dowolny algorytm //kasowanie odbywa si automatycznie return 0;
Odwiedzanie wierzchoªków Ni»ej przedstawione zostan dwa algorytmy odwiedzania wierzchoªków: BFS przeszukiwanie wszerz DFS przeszukiwanie w gª b
BFS void BFS(graf G, wierzcholek v) { char odwiedzone[ V(G) ]; //zerowanie S kolejka FIFO S.push(v) odwiedzone[v]=1; while(! S.empty() ) { foreach u in G.neigh(v) { if( odwiedzone[u]==0 ) { odwiedzone[u]=1; S.push(u); } } } }
S
S 3
S
S,, 2
S,, 2
S, 2
S, 2,
S, 2,
S 2,
S 2,,
S 2,,
S,
S,, 1
S,, 1
S, 1
S, 1,
S, 1,
S 1,
S 1,
S 1,
S
S
S
S
S
S
DFS void DFSViz(graf G, wierzcholek v, char odw[]) { odw[v] = 1; foreach u in G.neigh(v) { if( odw[u]==0 ) DFSViz(G, u, odw); } } void DFS(graf G, wierzcholek v) { char odwiedzone[ V(G) ]; DFS(G, v, odwiedzone); }
Znajdowanie najkrótszej ±cie»ki Mamy dany graf z dodatnimi wagami na kraw dziach oraz dwa wierzchoªki z tego grafu. W jaki sposób wyszuka najkrótsz drog pomi dzy tymi wierzchoªkami?
Algorytm Dijkstry int sciezka(graf G, wierz v1, wierz v2) { int odl[ V(G) ]; S- kolejka priorytetowa; foreach v in G odl[v] = ; odl[v1]=0; S.push(V(G)); while(! S.empty() ) { v = S.pop(); //element o najmniejszej wadze foreach u in G.neigh(v) { if( odl[u]>odl[v]+g.weight(u,v) ) odl[u] = odl[v]+g.weight(u,v); } } return odl[v2]; }
1 1 2 1 3 2 1 1 1 1 2 3
1 1 2 1 3 2 1 1 1 0 1 2 3
1 1 2 1 3 2 1 1 1 0 1 2 3
1 1 2 1 3 2 1 1 1 1 0 2 1 2 3
1 1 2 1 3 2 1 1 1 1 0 2 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3
1 1 2 1 3 2 1 1 1 2 1 0 2 3 1 2 3