Sunteți pe pagina 1din 12

Pb 1-Problema presupune o implementare pentru a doua varianta a parcuregii DF.

Asadar, stiva este


simulata cu ajutorul unui vector si se tine cont de faptul ca operatiile de adaugare, respectiv extragere a
unei informatii din stiva sunt posibile mereu in contextul unui algoritm de parcurgere.
#include<stdio.h>
#include<conio.h>
int insereaza_stiva(int *stiva, int n, int vf)
{
int i;
for (i = n - 1; i >= 0; i--)
stiva[i + 1] = stiva[i];
stiva[0] = vf;
n++;
return n;
}

int stergere_stiva(int * stiva, int n)


{
int i;
for (i = 0; i<n - 1; i++)
stiva[i] = stiva[i + 1];
n--;
return n;
}
int citire_stiva(int *stiva, int n)
{
return stiva[0];
}
int **aloca(int linii, int coloane)
{
int **a, i;
a = new int*[linii];
for (i = 0; i<linii; i++)
a[i] = new int[coloane];
return a;
}
int **dezalocare(int **a, int linii)
{
int i;
for (i = 0; i<linii; i++)
delete a[i];
delete a;
return a;
}
//parcurg DF
void depth_first(int v0, int **a, int n)
{
int *stiva, *m, i, nr_c, gasit, k;
stiva = new int[n];
m = new int[n];
for (int i = 0; i<n; m[i++] = 0);
nr_c = 0;
nr_c = insereaza_stiva(stiva, nr_c, v0);
m[v0] = 1;
printf("\n%i", v0 + 1);
while (nr_c)
{
i = citire_stiva(stiva, nr_c);
gasit = 0;
for (int k = 0; (k<n) && !gasit; k++)
if ((a[i][k] == 1) && (m[k] == 0))
{
nr_c = insereaza_stiva(stiva, nr_c, k);
m[k] = 1;
printf("\n%i", k + 1);
gasit = 1;

}
if (!gasit)
nr_c = stergere_stiva(stiva, nr_c);
}
delete stiva;
delete m;
}
void main()
{
int n, v0, **a, m, i, j, vf1, vf2;
//preiau graful de la tastatura
printf("Numarul de varfuri:");
scanf("%i", &n);
a = aloca(n, n);
for (i = 0; i<n; i++)
for (j = 0; j <= i; j++)
a[j][i] = a[i][j] = 0;
printf("Numarul de muchii:"); scanf("%i,", &m);
for (i = 0; i<m; i++)
{
printf("Varful initial:"); scanf("%i", &vf1);
printf("Varful final:"); scanf("%i", &vf2);
a[vf1 - 1][vf2 - 1] = a[vf2 - 1][vf1 - 1] = 1;
}
printf("\nVarful initial pentru parcurgerea DF");
scanf("%i", &v0);
printf("\nOrdinea de vizitare a varfurilor grafului este:");
depth_first(v0 - 1, a, n);
a = dezalocare(a, n);
_getch();}
Pb 2- Acest program verifica daca graful este conex si se afiseaza toate componentele sale
conexe;

#include<stdio.h>
#include<conio.h>
int n, m, a[20][20], viz[20], nrc = 0;
void viziteaza(int nod)
{
int i;
viz[nod] = nrc;
for (i = 1; i <= n; i++)
if (a[nod][i] == i && viz[i] == 0)
viziteaza(i);
}
void main()
{
int nod, i, j, x, y;
printf("Introdu numarul de noduri:");
scanf("%d", &n);
printf("Introdu numarul de muchii:");
scanf("%d", &m);
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
a[i][j] = 0;
printf("Introdu muchiile:\n");
for (i = 1; i <= m; i++)
{
printf("De la nodul: ");
scanf("%d", &x);
printf("La nodul:");
scanf("%d", &y);
a[x][y] = a[y][x] = 1;
}
for(nod=1;nod<=n;nod++)
if (viz[nod] == 0)
{
nrc++;
viziteaza(nod);
if (nrc == 1)
printf("Graful este conex!\n");
else
printf("Graful nu este conex!\n");
for (i = 1; i <= nrc; i++)
{
printf("Componenta %d:", i);
for (j = 1; j <= n; j++)
if (viz[j] == i)
printf("%d", j);
printf("\n");
}
_getch();
}

}
Pb 3-Acest program presupune aplicarea algoritmului lui Kruskal.

#include<stdio.h>
#include<conio.h>

int radacina(int v, int *tata)


{
int u = v;
while (tata[u] >= 0)
u = tata[u];
return u;
}

int kruskal(int a[][3], int nm, int nv)


{
int tata[50], i, j;
int v1, v2, k, p, c = 0;
for (i = 0; i<nv; i++)
tata[i] = -1;
for (j = i = 0; i<nv - 1; j++)
{
v1 = a[j][0];
v2 = a[j][1];
k = radacina(v2, tata);
p = radacina(v1, tata);
if (k - p)
{
if (tata[k]<tata[p])
{
tata[k] += tata[p];
tata[p] = k;
}
else
{
tata[p] += tata[k];
tata[k] = p;
}
c += a[j][2];
printf("%i -> %i cost %i\n", v1 + 1, v2 + 1, a[j][2]);
i++;
}
}
return c;
}

void main()
{
int cost, i, j, nv, nm, a[100][3];
//graful este preluat de la tastatura
printf("Numarul de virfuri:"); scanf("%i", &nv);
printf("Numarul de muchii:"); scanf("%i", &nm);
printf("Matricea de reprezentare\n");
for (i = 0; i<nm; i++)
{
printf("Muchia %i si ponderea:", i + 1);
for (j = 0; j<3; j++)
scanf("%i", &a[i][j]);
}
for (i = 0; i<nm; i++)
for (j = 0; j<2; j++)a[i][j]--;
printf("Arborele de cost minim: \n");
cost = kruskal(a, nm, nv);
printf("\ncu costul %i", cost);
_getch();
}

Pb 4-Acest program afiseaza drumul de la nodul initial(parintele) la nodurile frunza.


#include <stdio.h>
int cauta(int v[2][100], int n,int cautata)
{
int i=1,gasit=0,ok=0;

if (v[0][cautata] == 0) //daca ok ramane 0 inseamna ca suntem la inceput si nu


vrem sa afisam degeaba parintele tuturor asa ca verificam sa avem cel putin unul deja
vizitat
{
for (i = 1;i <= n;i++)
if (v[0][i] == cautata && v[1][i] == 1) ok = 1;
if (ok == 1)
printf("\n%d ", cautata);
}

i = 1; //restartam i
while (i <= n && v[1][i] == 1) i++;
if (i == n + 1)
return 0; //daca au fost toate prelucrate iesi din functie
else
{
for (i = 1;i <= n;i++)
if (v[0][i] == cautata && v[1][i] == 0) //daca nu a fost vizitat si
daca am gasit vom afisa varful corespunzator
{
printf("%d ", i);
v[1][i] = 1; //a fost prelucrat
cauta(v, n, i); //continuam cautarea pt urmatorul nod
gasit = 1;
}
if (gasit == 0)
cauta(v, n, v[0][cautata]); //daca nu am gasit altul intoarce-te
inapoi cu un pas (cauta parintele / urca-te mai sus pe arborele cautarii)
}
}
void main()
{
int v[2][100], i, n; //pe prima linie a matricei avem parintii iar pe a doua 0-
nevizitat si 1-vizitat/prelucrat
printf("cate varfuri? "); scanf("%d",&n);
printf("Vector parinti pentru cele %d varfuri: \n",n);
for (i = 1;i <= n;i++)
{
scanf("%d", &v[0][i]);
v[1][i] = 0; //toti sunt nevizitati la inceput
}
printf("\n");
printf("Drumuri de la varf initial (parintele tuturor) la noduri frunza:\n");
cauta(v, n, 0);
printf("\n\n");
}
Pb 5 Problema preia din tabela de muchii si parcurge in latime folosind vector de
distante:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INF 10000

//preluare graf din fisier text - prima linie: nr varfuri si nr muchii


//urmat linii cu tabela de muchii
unsigned char** citire_graf_neor(char* nume, int *n, int *m) //returnam pointerul t - tip
matrice
{
FILE* f;
int i;
unsigned char** t; //tabela muchii - nu are nevoie decat de un octet (de aceea
char) - e pointer
f = fopen(nume, "rt");
if (!f)
t = NULL; //nu s-a putut deschide => facem null pointerul
else
{
fscanf(f,"%d %d",&*n,&*m); //&* se anuleaza si se poate scrie direct n

t = new unsigned char*[*m]; //alocam m linii; m = nr muchii


for (i = 0;i < *m;i++)
t[i] = new unsigned char[2]; //alocam 2 spatii pe fiecare linie
//alocare spatiu tabela muchii

for (i = 0;i < *m;i++)


fscanf(f,"%d %d",&t[i][0],&t[i][1]);

fclose(f);
}
return t; //returnam tabela de muchii
}
//construire matr adiac stiind tabela de muchii
char** tab2ad(int n, int m, unsigned char** t) //returnam matricea; de aceea char**; tab
to ad = from TABel to ADiacent matrix
{
char** a; //matricea a
int i, j;

a = new char*[n];
for (i = 0;i < n;i++)
a[i] = new char[n];
for (i = 0;i < n;i++)
for (j = 0;j < n;j++)
a[i][j] = 0; //umplem toata matricea cu 0
for (i = 0;i < m;i++)
{
a[t[i][0] - 1][t[i][1] - 1] = 1; //indicele in matrice e vf-1; umplem
matricea cu 1 unde avem muchii
a[t[i][1] - 1][t[i][0] - 1] = 1; //ne asiguram ca umplem simetric
}
return a;
}

//parcurgere in latime cu vector distante


unsigned char* BF_distante(char** a, int n, int v0 /*vf initial*/, int &nvp /*nr vf
prelucrate*/, int* &p /*vector parinti*/) //returnam lista de ordine-un vector simplu
{
unsigned char* lista;
int* d; //vector de distante - variab locala in subp, nu avem nev de el in main,
dar de parinti avem asa ca am trecut ca parametru parintii
int i, j, k;
int gata;
int v;//vf curent-nu e neaparata nevoie de el

d = new int[n];
p = new int[n];
lista = new unsigned char[n];
nvp = 0;//nr vf prelucrate e 0 la inceput
for (i = 0;i < n;i++)
d[i] = p[i] = INF;
d[v0 - 1] = 0; //distanta de la vf initial la el insusi e 0; indice corespunzator
e cu -1
p[v0 - 1] = 0; //vf init nu are parinte
i = 0;//distanta porneste de la zero si va creste in while
gata = 0; //pt a stii daca am gasit sau nu noi varfuri nevizitate
while (!gata)
{
gata = 1;
for(j=0;j<n;j++) // j este indicele varfului
if (d[j] == i) //daca am gasit un varf cu o anumita distanta cautata
{
v = j + 1;//vf curent- nu aveam neaparata nev de variabila v
lista[nvp++] = v; //trecem in lista de ordine varful; creste
nr de vf prelucrate
for(k=0;k<n;k++)
if (a[j][k] == 1 && d[k] == INF) //cautam pe linia
varfului unde avem 1 inseamna ca are vecin / exista muchie; sa aiba distanta infinit =
nevizitat inca
{
//daca am gasit un vecin nevizitat
d[k] = i + 1; //ii trecem distanta
p[k] = v; //trecem parintele
gata = 0;
}
}
i++;//crestem distanta
}
delete d; // nu mai avem nev de vector distante
return lista;//returnam lista cu ordinea-un vector
}

void main()
{
char numef[50] = "..\\graf.txt";
int nr_vf, nr_muc;
int i;
unsigned char** tab; //tabela muchii
char** ad; //matr adiacenta
int vi;//vf initial
unsigned char* ordine; //lista de ordine
int* parinti;
int vparc; //nr vf parcurse

tab = citire_graf_neor(numef,&nr_vf,&nr_muc);
if (tab==NULL)
printf("\nNu pot deschide fisierul. Nu se poate prelua\n");
else
{
ad = tab2ad(nr_vf, nr_muc, tab);
printf("\nVf. initial: "); scanf("%d",&vi);
ordine = BF_distante(ad,nr_vf,vi,vparc,parinti);
printf("\nOrdine de parcurgere: ");
for (i = 0;i < vparc;i++)
printf("%d ",ordine[i]);
printf("\nParinti:");
for (i = 0;i < nr_vf;i++)
printf("\nVf %2d a fost descoperit de vf %2d",i+1,parinti[i]);
}
printf("\n\n");
}
Pb 6-Convertire reprezentare tabelara a unui graf in reprezentare matriceala-pentru graf
neponderat se genereaza matricea de adiacenta.

#include <stdio.h>
#include <malloc.h>

int** conversie_n(int nrv, int nrm, int** tabel)


{
int i, j;
int** mat;

mat = (int**)malloc(nrv * sizeof(int*));


for (i = 0; i < nrv; i++)
mat[i] = (int*)malloc(nrv * sizeof(int));
for (i = 0; i < nrv; i++)
for (j = 0; j < nrv; j++)
mat[i][j] = 0;
for (i = 0; i<nrm; i++)
{
mat[tabel[i][0] - 1][tabel[i][1] - 1] = 1;
mat[tabel[i][1] - 1][tabel[i][0] - 1] = 1;
}
return mat;
}
void main()
{
int nrv, nrm, dim;
int i, j;
int** tab;
int** mat;

printf("Varfuri:"); scanf("%d", &nrv);


printf("Nr muchii:"); scanf("%d", &nrm);
tab = new int*[nrm];
for (i = 0; i < nrm; i++)
tab[i] = new int[2];
printf("Tabela muchii:\n");
for ( i = 0; i <nrm; i++)
for ( j = 0; j < 2; j++)
scanf("%d", &tab[i][j]);
mat = conversie_n(nrv, nrm, tab);
printf("\n");
for (i = 0; i < nrv; i++)
{
for (j = 0; j < nrv; j++)
printf("%d", mat[i][j]);
printf("\n");
}

Pb 7- In problema se da un graf neorientat cu n varfuri si m muchii. Vom afisa grupurile de muchii


incidente.

#include <stdio.h>

void citire(int *n, int* m,int a[100][100])


{
int i,j; int x, y;
scanf("%d %d",n,m);
for (i = 0; i < *n; i++)
for (j = 0; j < *n; j++)
a[i][j] = 0;
for ( i = 0; i < *m; i++)
{
scanf("%d", &x);
scanf("%d", &y);
a[x - 1][y - 1] = 1;
a[y - 1][x - 1] = 1;
}
}

int grad(int v,int n,int a[100][100]) //gradul nodului v


{
int g = 0; int i;
for (i = 0; i < n; i++)
g = g + a[v-1][i];
return g;
}

void main()
{
int n, m, a[100][100];
int i, j;
citire(&n,&m,a);
for (i = 0; i < n; i++)
if (grad(i+1,n,a) >= 2)
{
for (j = 0; j < n; j++)
if (a[i][j] == 1)
printf("[%d,%d] ",i+1,j+1);
printf("\n");
}

S-ar putea să vă placă și