Conex-bipartit
Enunt
În fişerul text graf.in este memorat un graf neorientat conex astfel:
pe prima linie un număr natural n, care reprezintă numărul de noduri ale unui graf neorientat.
pe următoarele linii sunt memorate câte două numere naturale care reprezintă muchiile grafului.
Scrieţi un program care să determine dacă graful dat este bipartit.
(Definiţie:Un graf G=(X,U) se numeşte bipartit dacă există o partiţie a mulţimii nodurilor X=X1UX2, X1 intersectat cu X2 = Ø, astfel încât fiecare muchie a lui G are o extremitate în mulţimea X1 şi cealaltă în X2.Detalii suplimentare...)
Exemplu:
Continutul fişierului text graf.in
7
1 2
1 3
1 5
2 4
3 7
4 6
6 7
Rezultate asteptate
Graf bipartit!
Graful memorat în fişerul text de mai sus are următorul aspect grafic:
Graful rearanjat astfel încât să se observe cele două submultimi:
X1={2,3,5,6} si x2={1,4,7}
Rezolvare: Ideea de rezolvare are la baza un algoritm de parcurgere a grafurilor neorientate. Vom folosi în continuare algoritmul de parcurgere în lăţime. Astfel vom marca alternativ nodurile vizitate ale grafului astfel:
dacă nodul din prima poziţie din coadă are valoarea 1, atunci toate nodurile adiacente cu el şi nevizitate vor fi marcate cu 2
dacă nodul din prima poziţie din coadă are valoarea 2, atunci toate nodurile adiacente cu el şi nevizitate vor fi marcate cu 1
La sfârşit vom verifica în vectorul v, dacă între nodurile marcate cu acelaşi număr exista muchie. În cazul în care vom găsi cel mult o pereche de noduri x,y care sunt marcate cu aceiaşi etichetă ( v[x]=v[y] ) şi între nodul x şi nodul y există muchie ( a[x][y]=1 ) atunci putem spune cu certitudine că graful nu este bipartit.
Programul C++ este:
#include<iostream>
#include<fstream>
using namespace std;
int a[20][20],c[20],v[20],ns,n,comp;
int prim;
int ultim;
// citirea grafului din fisier text si construirea matricei de adiacenta
void citire(int a[20][20], int &n)
{ ifstream f("graf.in");
int x,y;
f>>n;
while(f>>x>>y)
a[x][y]=a[y][x]=1;
f.close();
}
// afisarea pe ecran a matricei de adiacenta
void afisare(int a[20][20],int n)
{ cout<<"Matricea de adiacenta este : "<<endl;
for( int i=1;i<=n;i++)
{ for(int j=1;j<=n;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}
// returnează primului nod nevizitat
int exista_nod_nevizitat(int v[20], int n)
{ for(int i=1;i<=n;i++)
if(v[i]==0)
return i; // primul nod nevizitat
return 0; // nu mai exista noduri nevizitate
}
// parcurgerea în latime a unei componente conexe, plecând din nodul de start ns
void parcurgere_latime(int a[20][20], int n,int ns)
{ comp++;
v[ns]=1;
prim=ultim=1;
c[ultim]=ns;
while(prim<=ultim)
{for(int i=1;i<=n;i++)
if(a[c[prim]][i]==1)
if(v[i]==0)
{ ultim++;
c[ultim]=i;
if (v[c[prim]]==1)
v[i]=2;
else
v[i]=1;
}
prim++;
}
}
//verific daca graful este bipartit
int bipartit(int v[20],int n)
{
for(int x=1;x<n;x++)
for(int y=x+1;y<=n;y++)
if(v[x]==v[y])
if(a[x][y]==1)
return 0;
return 1;
}
// functia principala main()
int main()
{ citire(a,n);
afisare(a,n);
ns=1;
parcurgere_latime(a,n,ns);
if (bipartit(v,n))
cout<<"Graf BIPARTIT! ";
else
cout<<"Graful NU este BIPARTIT! ";
return 0;
}