Laborator 7
TDA GRAF. IMPLEMENTARE
Aplicatia 1
Sa se redacteze un program interactiv pentru prelucrarea unui graf implementat prin structuri de adiacenta:
o functie pentru inserarea unui nod in graf;
o functie pentru suprimarea unui nod din graf (se vor suprima si arcele aferente, daca exista);
o functie pentru inserarea unui arc intre doua noduri existente;
o functie pentru suprimarea unui arc intre doua noduri existente;
o functie care returneaza numarul de componente conexe ale grafului;
o functie care returneaza 1 daca nodurile grafului pot fi colorate cu 2 culori diferite astfel incat sa nu existe 2 noduri adiacente colorate cu aceeasi culoare si 0 in caz contrar;
o functie care apeleaza functia anterioara si daca aceasta returneaza 1, afiseaza o posibila solutie de colorare gasita.
rezolvare
Aplicatia 2
Sa se redacteze un program interactiv care prelucreaza cuvinte de aceeasi lungime L (de exemplu, L=5), implementand urmatoarele functii:
o functie pentru citirea unui nou cuvant (functia va verifica lungimea noului cuvant si daca este diferita de L, nu va adauga cuvantul);
o functie pentru suprimarea unui cuvant;
o functie pentru afisarea cuvintelor existente;
o functie care citeste doua cuvinte, verifica existenta lor in evidenta si gaseste cel mai scurt drum dintre ele (vezi mai jos).
Pentru aceasta aplicatie, consideram ca intre 2 cuvinte exista un drum de lungime 1 daca ele difera printr-o singura litera si nu exista drum daca ele difera prin mai mult de o litera. Astfel, daca cuvintele din evidenta sunt CERNE, CARNE, CARTE, CERTE, CURTE, CURBE, CURSE, BURSE atunci cel mai scurt drum intre CARTE si BURSE este: CARTE - CURTE - CURSE - BURSE.
Pentru implementare, veti folosi un graf, cuvintele fiind noduri ale grafului. Intre doua cuvinte exista arc daca ele difera printr-o singura litera si nu exista arc in caz contrar. Drumul minim intre 2 cuvinte va fi gasit printr-o cautare prin cuprindere in acest graf.
rez
#define NumarNoduri 100
typedef int TipCheie;
typedef int TipInfo;
typedef struct TipElement {
TipCheie cheie;
TipInfo info;
} TipElement;
typedef unsigned int TipContor; //[0, NumarNoduri]
typedef unsigned int TipIndex; //[1, NumarNoduri]
typedef TipElement TipTablouElem[NumarNoduri]; //
typedef int TipMatrAdj[NumarNoduri][NumarNoduri]; //doar valori boolene
typedef struct Graf {
TipContor Contor;
TipTablouElem Noduri;
TipMatrAdj Arce;
} Graf;
typedef struct TipArc {
TipIndex linie, coloana;
} TipArc;
Graf g;
void InserNod(Graf *g, TipElement e)
{
TipIndex i;
g->Contor++;
//se adauga elementul e in noul nod
g->Noduri[g->Contor] = e;
//se initializeaza matricea de adiacenta pentru noul nod
for(i = 1; i <= g->Contor; i++)
{
g->Arce[i][g->Contor] = 0;
g->Arce[g->Contor][i] = 0;
}
}
void InserArc(Graf *g, TipArc indicArc)
{
g->Arce[indicArc.linie][indicArc.coloana] = 1;
g->Arce[indicArc.coloana][indicArc.linie] = 1;
}
void SuprimNod(Graf *g, TipIndex indicNod)
{
TipIndex i;
//nodul indicat este inlocuit cu ultimul nod
g->Noduri[indicNod] = g->Noduri[g->Contor];
for(i = 1; i <= g->Contor; i++)
{
g->Arce[i][indicNod] = g->Arce[i][g->Contor];
g->Arce[indicNod][i] = g->Arce[g->Contor][i];
}
g->Contor--;
}
void SuprimArc(Graf *g, TipArc indicArc)
{
g->Arce[indicArc.linie][indicArc.coloana] = 0;
g->Arce[indicArc.coloana][indicArc.linie] = 0;
}
Alte lucruri:
define N_MAX 100
typedef struct Nod {
int nume; //index; se poate tine minte direct cheia
struct Nod *legatura;
} Nod;
Nod *StrAdj[N_MAX];
typedef int TipCheie;
typedef int TipInfo;
typedef struct TipElement {
TipCheie cheie;
TipInfo info;
} TipElement;
typedef struct Adj {
TipCheie cheieAdj;
struct Adj *urmAdj;
} Adj;
typedef struct Nod {
TipElement elem;
struct Nod *urmNod;
Adj *incepAdj;
} Nod;
typedef struct TipArc {
Nod *v1, *v2;
} TipArc;
typedef Nod* Graf;
Graf g;
typedef int ATOM;
typedef struct CelulaListNod* POZITIE;
typedef struct CelulaListArc {
int data; //informatia arcului
POZITIE nod; //destinatia arcului
struct CelulaListArc *urm; //inlantuire in liste de arce
} CelulaListArc;
typedef struct CelulaListNod {
ATOM data; //informatia apartinand nodului
POZITIE nod;
CelulaListArc *urm;
} CelulaListNod;
typedef struct ARC {
POZITIE nod1, nod2;
} ARC;
typedef POZITIE GRAF;
void CautaInAdancime(Graf *g, Nod x)
{
/*se parcurg toate nodurile din aceeasi componenta
conexa cu x prin cautare in adancime*/
Nod y;
marc[x] = vizitat; //=1
for(/* fiecare nod y din lista de adiacenta a lui x*/)
if(marc[y] == nevizitat) //==0
CautaInAdancime(g, y);
}
void TraversareInAdancime(Graf *g)
{
Nod x;
for(/*fiecare nod x din graful g*/)
marc[x] = nevizitat; //=0
for(/*fiecare nod x din graful g*/)
if(marc[x] == nevizitat) //==0
CautaInAdancime(g, x);
}
void CautaPrinCuprindere(Graf *g, Nod x)
{
/*se parcurg toate nodurile din aceeasi componenta
conexa cu x prin cautare prin cuprindere*/
CoadaNoduri Q;
Nod y;
ADAUGA(Q, x);
while(VID(Q) == 0)
{
x = SCOATE(Q);
marc[x] = vizitat; //=1
for(/* fiecare nod y din lista de adiacenta a lui x*/)
if(marc[y] == nevizitat) //==0
{
marc[y] = vizitat; //=1
ADAUGA(Q, y);
}
}
}
void TraversarePrinCuprindere(Graf *g)
{
Nod x;
for(/*fiecare nod x din graful g*/)
marc[x] = nevizitat; //=0
for(/*fiecare nod x din graful g*/)
if(marc[x] == nevizitat) //==0
CautaPrinCuprindere(g, x);
}
int Articulatie(int x)
{
Nod *t;
int m, min;
id++;
marc[x] = id;
min = id;
t = StrAdj[x];
while(t != NULL)
{
if(marc[t->nume] == nevizitat) //==0
{
m = Articulatie(t->nume);
if(m < min)
min = m;
if(m >= marc[x])
printf("%d este punct de articulatie\n", x);
}
else
//daca unul din stramosi poate deja ajunge mai sus
if(marc[t->nume] < min)
min = marc[t->nume];
t = t->urm;
}
return min;
}
Problema:
Determinati numarul componentelor conexe si faceti parcurgea in adancime:
#include <iostream>
#include <fstream>
#define MAX 100
using namespace std;
int numarNoduri;
char matriceAdiacenta[MAX][MAX];
char vector[MAX];
char vizitat[MAX];
void citire()
{
ifstream f("graf.txt");
int i,j;
f>>numarNoduri;
for(i=0;i<numarNoduri;i++)
f>>vector[i];
for(i=0;i<numarNoduri;i++)
for(j=0;j<numarNoduri;j++)
f>>matriceAdiacenta[i][j];
f.close();
}
void parcurgere(int nod)
{
vizitat[nod]=1;
int vecin;
for(vecin=0;vecin<numarNoduri;vecin++)
if(matriceAdiacenta[nod][vecin]=='1')
if(vizitat[vecin]==0)
parcurgere(vecin);
}
int nrcomponente()
{
int i,cc=0;
for(i=0;i<numarNoduri;i++)
if(vizitat[i]==0)
{
parcurgere(i);
cc++;
}
return cc;
}
void afisare()
{
for(int i=0;i<numarNoduri;i++)
{
cout<<vector[i]<<" ";
parcurgere(i);
}
}
int main()
{
cout << "Hello world!" << endl;
citire();
cout<<"Numarul componentelor conexe este: "<<nrcomponente()<<endl;
afisare();
return 0;
}