Вы находитесь на странице: 1из 16

Algoritmul lui Warshall

1.

Codul surs

#include<stdio.h> #include<math.h> #include<ctype.h> #include<graphics.h> #include<conio.h> #include<stdlib.h> #define maxN 20 #define pi M_PI #define R 200 #define r 20 #define CALEA "C:\\BorlandC\\BGI" typedef char TipCheie; typedef TipCheie TipEl; typedef TipEl TipTabEl[maxN]; typedef int TipMatAdi[maxN][maxN]; typedef int TipContor; typedef struct { int lin; int col;

}TipArc; typedef struct { TipContor Contor; TipTabEl Noduri; TipMatAdi Arce; }Graf; Graf g; TipEl e; int IndiceNod; TipArc IndiceArc; int i,j,k; double x0,y0,xi,yi,xj,yj,x1,y1,x2,y2,x3,y3; double alfa,alfa1,alfa2; char optiune,ch; TipMatAdi Adi,Drum; void afisareNoduri(void) { char s[2]={0,0}; double xi,yi; int i; x0=(getmaxx()/2)+80; y0=getmaxy()/2; for(i=0;i<g.Contor;i++) { xi=x0+R*cos(2*pi*i/g.Contor);

yi=y0-R*sin(2*pi*i/g.Contor); setcolor(WHITE); pieslice(xi,yi,0,360,r); setcolor(BLACK); s[0]=g.Noduri[i]; settextstyle(2,0,5); outtextxy(xi,yi,s); } }/*afisareNoduri*/ void afisareGraf(void) { int i,j,xi,yi,xj,yj; x0=(getmaxx()/2)+80; y0=getmaxy()/2; if(g.Contor==0) printf("Graful este vid!\n"); else { afisareNoduri(); for (i=0;i<g.Contor;i++) for (j=0;j<g.Contor;j++) if (g.Arce[i][j]==1) { xi=x0+R*cos(2*pi*i/g.Contor); yi=y0-R*sin(2*pi*i/g.Contor); xj=x0+R*cos(2*pi*j/g.Contor); yj=y0-R*sin(2*pi*j/g.Contor); alfa=atan2(yj-yi,xi-xj); x1=xj+r*cos(alfa);

y1=yj-r*sin(alfa); alfa1=alfa+0.2; x2=x1+15*cos(alfa1); y2=y1-15*sin(alfa1); alfa2=alfa-0.2; x3=x1+15*cos(alfa2); y3=y1-15*sin(alfa2); setcolor(WHITE); line(xi,yi,x1,y1); line(x1,y1,x2,y2); line(x1,y1,x3,y3); x4=x1+(xi-x1)/5; y4=y1-(yi-y1)/5-10 ; sprintf(sir,"%d",g.Arce[i][j].val); outtextxy(x4,y4,sir); } } } void InserNod(Graf *g,TipEl e) { int i; g->Contor++; g->Noduri[g->Contor-1]=e; for(i=0;i<=g->Contor-1;i++) { g->Arce[g->Contor-1][i]=0; g->Arce[i][g->Contor-1]=0;

} }/*InserNod*/ void InserArc(Graf *g,TipArc IndiceArc) { g->Arce[IndiceArc.lin][IndiceArc.col]=1; }/*InserArc*/ void SuprimaNod(Graf *g,int IndiceNod) { int i; g->Noduri[IndiceNod]=g->Noduri[g->Contor-1]; for(i=0;i<g->Contor;i++) { g->Arce[IndiceNod][i]=g->Arce[g->Contor-1][i]; g->Arce[i][IndiceNod]=g->Arce[i][g->Contor-1]; } g->Contor--; }/*SuprNod*/ void SuprimaArc(Graf *g,TipArc IndiceArc) { g->Arce[IndiceArc.lin][IndiceArc.col]=0; g\ }/*suprimare arc*/ void init_mod_grafic(void) { /* request auto detection */ int gdriver = DETECT, gmode, errorcode;

/* initialize graphics mode */ initgraph(&gdriver, &gmode, CALEA); /* read result of initialization */ errorcode = graphresult(); if (errorcode != grOk) /* an error occurred */ { printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); /* return with error code */ getch(); } } void asteptare(void) { printf("Apasati orice tasta pentru contiunuare...\n"); getch(); } void afisare_matrice(TipMatAdi Adi) { for (i=0;i<g.Contor;i++) { for (j=0;j<g.Contor;j++) printf("%d ",Adi[i][j]);

printf("\n"); } } int CautNod(Graf g,TipCheie cheia) { int i; for(i=0;i<g.Contor;i++) if(g.Noduri[i]==cheia) return i; return -1; } void Atribuire(TipMatAdi a,TipMatAdi b) { for (i=0;i<g.Contor;i++) for (j=0;j<g.Contor;j++) a[i][j]=b[i][j]; } void warshall(TipMatAdi Adi,TipMatAdi Drum) { Atribuire(Drum,Adi); for (k=2;k<=g.Contor;k++) for (i=0;i<g.Contor;i++) if (Drum[i][k]==1) for (j=0;j<g.Contor;j++) Drum[i][j]=Drum[i][j]||Drum[k][j]; } void Creare(Graf *g) {

int i,j,xi,yi,xj,yj,n; char ch,c; g->Contor=0; /* initializarea efectiva a grafului for (i=0;i<g->Contor;i++) g->Noduri[i]=' '; for (i=0;i<g->Contor;i++) for (j=0;j<g->Contor;j++) g->Arce[i][j]=0; */ printf("Introduceti numarul de noduri:");scanf("%d",&n); for (i=0;i<n;i++) { printf("Introduceti cheia nodului:");fflush(stdin); scanf("%c",&e);e=toupper(e); InserNod(g,e); } if(g->Contor!=0) { init_mod_grafic(); afisareNoduri(); printf("Introduceti arcele:\n"); printf("Introduceti arc?(D/N):"); fflush(stdin);scanf("%c",&c);c=toupper(c); while(c=='D') { printf("Introduceti primul nod:");

fflush(stdin);scanf("%c",&ch); ch=toupper(ch); IndiceArc.lin=CautNod(*g,ch); if((IndiceArc.lin>=0)&&(IndiceArc.lin<(*g).Contor)) { printf("Introduceti nodul de sosire:"); fflush(stdin);scanf("%c",&ch);ch=toupper(ch); IndiceArc.col=CautNod(*g,ch); if((IndiceArc.col>=0)&&(IndiceArc.col<(*g).Contor)) { InserArc(g,IndiceArc); xi=x0+R*cos(2*IndiceArc.lin*pi/ (*g).Contor); yi=y0-R*sin(2*IndiceArc.lin*pi/ (*g).Contor); xj=x0+R*cos(2*IndiceArc.col*pi/ (*g).Contor); yj=y0-R*sin(2*IndiceArc.col*pi/ (*g).Contor); alfa=atan2(yj-yi,xi-xj); x1=xj+r*cos(alfa); y1=yj-r*sin(alfa); alfa1=alfa+0.2; x2=x1+15*cos(alfa1); y2=y1-15*sin(alfa1); alfa2=alfa-0.2;

x3=x1+15*cos(alfa2); y3=y1-15*sin(alfa2); setcolor(WHITE); line(xi,yi,x1,y1); line(x1,y1,x2,y2); line(x1,y1,x3,y3); x4=x1+(xi-x1)/5; y4=y1-(yi-y1)/5-10 ; sprintf(sir,"%d",g.Arce[i][j].val); outtextxy(x4,y4,sir); } else printf("Ati tastat nume nod gresit!\n"); } else printf("Ati tasta nume nod gresit!\n"); printf("Introduceti (D/N):");fflush(stdin);scanf("%c",&c); c=toupper(c); }/*while*/ closegraph(); } } void main(void) { clrscr(); g.Contor=0; do arc?

{ clrscr(); printf("Operatii asupra grafurilor implementate cu matrici de adiacenta\n"); printf("A-AfisareGraf\n"); printf("C-Creare\n"); printf("I-Inserare noduri\n"); printf("N-Inserare arce\n"); printf("S-Stergere noduri\n"); printf("T-Sterge arce\n"); printf("W-algoritmul lui Warshall\n"); printf("X-exit\n"); printf("Introduceti optiunea:");fflush(stdin);scanf("%c",&optiune); optiune=toupper(optiune); switch(optiune) { case 'A': init_mod_grafic(); afisareGraf(); asteptare(); closegraph(); break; case 'C': clrscr(); Creare(&g); break; case 'I': clrscr();

printf("Introduceti cheia nodului:"); fflush(stdin);scanf("%c",&e);e=toupper(e); InserNod(&g,e); init_mod_grafic(); afisareGraf(); asteptare(); closegraph(); break; case 'N': clrscr(); if(g.Contor>0) { printf("Introduceti pornire:");

nodul

de

fflush(stdin);scanf("%c",&ch);ch=toupper(ch); IndiceArc.lin=CautNod(g,ch); if((IndiceArc.lin>=0)&&(IndiceArc.lin<g.Contor)) { printf("Introduceti nodul de sosire:"); fflush(stdin);scanf("%c",&ch); ch=toupper(ch); IndiceArc.col=CautNod(g,ch); if((IndiceArc.col>=0)&&(IndiceArc.col<g.Contor)) {

InserArc(&g,IndiceArc); init_mod_grafic(); afisareGraf(); asteptare(); closegraph(); } else printf("Ati tastat nume nod sosire gresit!\n"); } else printf("Ati tasat nume nod pornire gresit!\n"); } else printf("Graful este vid!\n"); asteptare(); break; case 'S': clrscr(); if(g.Contor>0) { printf("Introduceti nodul de suprimat:"); fflush(stdin);scanf("%c",&ch); ch=toupper(ch); IndiceNod=CautNod(g,ch); if((IndiceNod>=0)&&(IndiceNod<g.Contor)) { SuprimaNod(&g,IndiceNod);

init_mod_grafic(); afisareGraf(); asteptare(); closegraph(); } else printf("Ati tasta nume nod gresit!\n"); } else printf("Graful este vid!\n"); asteptare(); break; case 'T': clrscr(); if(g.Contor>0) { printf("Introduceti nodul de pornire:"); fflush(stdin);scanf("%c",&ch); ch=toupper(ch); IndiceArc.lin=CautNod(g,ch); if((IndiceArc.lin>=0)&&(IndiceArc.lin<g.Contor)) { printf("Introduceti nodul de sosire:"); fflush(stdin);scanf("%c",&ch); ch=toupper(ch) ;

IndiceArc.col=CautNod(g,ch); if((IndiceArc.col>=0)&&(IndiceArc.col<g.Contor)) { if(g.Arce[IndiceArc.lin][IndiceArc.col]) { SuprimaArc(&g,IndiceArc); init_mod_grafic(); afisareGraf(); asteptare(); closegraph() ; } else printf("Arcul dat nu exista in graf\n"); } else printf("Ati tastat nod sosire gresit\n"); } else printf("Ati tasta nod pornire gresit!\n"); } else printf("Graful este vid!\n"); asteptare() ; break; case 'W': printf("Matricea de adiacenta:\n"); afisare_matrice(g.Arce); asteptare(); printf("Matricea drumurilor:\n"); warshall(g.Arce,Drum);

afisare_matrice(Drum); asteptare(); break; case 'X': break; default : printf("Ati grasita!\n"); asteptare(); break; }/*switch*/ }while(optiune!='X'); }/*main*/ tastat aoptiune

2.

Observaii:

Oridecte ori avem de determinat matricea Drumurilor asociat unui graf vom ultiliza Algoritmul lui Warshall deoarece acesta este mult mai eficient dect algoritmul clasic de determinare a nchiderii tranzitive.