Vous êtes sur la page 1sur 33

include

<DOS.h>
#include
<graphics.h>
#include
<IOStream.h>
#include
<IOManip.h>
#include
<FStream.h>
#include
<ConIO.h>
#include
<StdIO.h>
#include
<StdLib.H>
#include
<DOS.h>
#include
<String.H>
#include
<CType.H>
#include
<Math.H>
//******************************************************************************
//
INICIO
DE
IMPLEMENTACION
ALGOTIMOS
PARA
GRAFO
DIRIGIDO
//******************************************************************************
//----------------------------------------------------------------------------------//Declaracin
de
prototipos
de
funciones:
void
Cursor(int
X,int
Y,char
*Cad,int
Color,int
pos,
int
Oprimido);
void
Ventana(int
x1,
int
y1,
int
x2,
int
y2,
int ColorArribaIzquierda, int ColorAbajoDerecha,
int
ColorFondo);
void
Icono1(int
x,
int
y);
void
Icono2(int
x,
int
y);
void
Icono3(int
x,
int
y);
//----------------------------------------------------------------------------------//Definiciones
de
constantes:
const
unsigned
long
Infinito=4294967295/2;//M ximo
unsigned
long
//advertencia:
Solo
utilizar
pesos
de
aristas
hasta
4294967295/2
//esto
debido
a
que
tendremos
que
hacer
comparaciones
de
//infinito>infinito
+
peso
y
no
nos
dara
el
c lculo.
//Si el peso de las aristas tiene decimales, cambiar todos los unsigned int
//de
este
programa,
al
tipo
num,rico
conveniente
const
char
NombreArch[20]
=
"Dijkstr5.Gfa";
const
int
AltoIcono=20,
AnchoIcono=150,
MaxIco=3,
Xi=1,
Yi=1,
DeltaX=AnchoIcono+2,
PaletaXi=1,
PaletaYi=460,
AltoPaleta=20,
LargoPaleta=40,
MaxColores=16,
EspacioGrafoXo=0,
EspacioGrafoYo=AltoIcono+2,
EspacioGrafoXf=639,
EspacioGrafoYf=479-AltoPaleta,
AnchoVertice=10; //del cuadrado que representa cada v,rtice en pantalla
//----------------------------------------------------------------------------//Definiciones
de
de
tipos
de
datos
registros(struct)
typedef
struct
VERTICE
VERTICE;

typedef
typedef
typedef
struct
char

struct
struct
struct
unsigned
NombreDestino;
//

ARISTA
INFOVERTICE
INFOARISTA

Etiqueta

del

long
v,rtice

de

destino

ARISTA;
INFOVERTICE;
INFOARISTA;
INFOARISTA{
PesoArista;
de la arista

};
struct
INFOARISTA
Info;
//
informacin
de
cada
VERTICE *Ady;
//puntero desde el v,rtice de origen al v,rtice de
ARISTA
*Sig;
//puntero
en
la
lista
anlazada
de

ARISTA{
arista
destino
aristas

};
struct

INFOVERTICE{
char
NombreVertice;
//
Etiqueta
del
v,rtice
char
Estado;
//En
los
recorridos.
1:Preparado,
2:Espera,
3:Procesado
int
x,
y;
//Posicin
del
v,rtice
en
la
pantalla
unsigned long d; //En algoritmo de Dijkstra es distancia acumulada mnima

};
struct

VERTICE{
INFOVERTICE
Info;
//Informacin
propia
de
cada
nodo.
ARISTA *Cab;//Apunta a cada sublista desde cada nodo de la lista principal
VERTICE *Sig;//Apunta al siguiente v,rtice en la lista enlazada. El siguiente
//vertice no quiere decir que este adyacente en el grafo, esto
//Solo ser, de casualidad. Para los adyacentes ver struct ARISTA
VRTICE *Predecesor; //En algunos recorridos, ser el v, rtice anterior.
//El padre si vemos el recorrido como un rbol.
//En otros casos, no aun aqu, podra ser una lista de los
//Nodos que llegan a este(es decir aristas que llegan)

};
//----------------------------------------------------------------------------------//Definicin
de
variables
globales:
struct VERTICE *CAB=NULL;// variable global la cual apuntar a la cabeza de la
// lista simplemente enlazada que almacena los v,rtices(nodos) del grafo.
fstream
BufferArchivo;
//
char
*IDVertices;
//para
cada
v,rtice
se
utilizaran
letras
maysculas(26)
//como se ve es trivial superar la cantidad de 26
int
N=0;//Este
ser
el
nmero
de
v,rtices
en
el
grafo.
int
PosIcoX[MaxIco];
//Definicin
de
arreglo
de
punteros
a
funciones:
void
(*Icono[MaxIco])(int,
int)
=
{Icono1,Icono2,Icono3};
//----------------------------------------------------------------------------------//A
continuacin
las
funciones
del
programa
//-----------------------------------------------------------------------------------

VERTICE *InsertarVerticeEnGrafo (INFOVERTICE Item){//Inserta en la lista principal


VERTICE
*p,
*q,
*NuevoNodo;
NuevoNodo
=
new(VERTICE);
if
(
NuevoNodo
==
NULL
)
{
cout
<<
"No
hay
memoria
suficiente";
return(NULL);
//
No
insertado
}
p
=
NULL;
q
=
CAB;
while
(q
!=
NULL
&&
Item.NombreVertice
>
q->Info.NombreVertice){
p
=
q;
q
=
q->Sig;
}
if
(q
&&
Item.NombreVertice
==
q->Info.NombreVertice)
{
delete(NuevoNodo);
return
(NULL);
//repetido,
}
NuevoNodo->Info
=
Item;
NuevoNodo->Sig
=
q;
NuevoNodo->Cab
=
NULL;
if
(
p
==
NULL)
CAB
=
NuevoNodo;
//era
el
primero
de
la
lista
else
p->Sig
=
NuevoNodo;
//"caso
general"
return(NuevoNodo);
//
insertado
}
//----------------------------------------------------------------------------------int
EliminarVerticeDelGrafo(VERTICE
*p){
VERTICE
*q;
if
(p
==
CAB)
CAB
=
p->Sig;
//eliminado
el
primer
VERTICE
de
la
lista
else
{
q
=
CAB;
while
(q->Sig
!=
p)
q
=
q->Sig;
q->Sig
=
p->Sig;
}
delete(p);
return
1;
}
//----------------------------------------------------------------------------------VERTICE*
EncontrarVerticeDelGrafo(INFOVERTICE
Item){
VERTICE
*p;

while
if(p

&&

p
&&

CAB;
(p
Item.NombreVertice
>
p->Info.NombreVertice)
p
=
p->Sig;
Item.NombreVertice != p->Info.NombreVertice)
// No encontrado
p=
NULL;
return
p;

}
//----------------------------------------------------------------------------------void
ListarVerticesDelGrafo(){
if
(!CAB)
cout
<<
"Lista
vaca
\a";
else
{
VERTICE
*p
=
CAB;
int
i=0;
cout
<<
"Orden
en
lista
Etiqueta\n";
while
(
p
){
cout
<<
setw(5)
<<
++i
<<
"
"
<<
p->Info.NombreVertice
<<
endl;
p
=
p->Sig;
}
}
}
//----------------------------------------------------------------------------------void
CapturarVertice(char
Grafico){
INFOVERTICE
Item;
if(Grafico=='S'){
}
else{
cout
<<
"\n\Nombre
de
la
etiqueta
del
v,rtice:
";
Item.NombreVertice
=
getche();
}
if
(
InsertarVerticeEnGrafo(Item)
==
0
){
cout
<<
"\n\nRepetido
\a";
getch();
}
}
//----------------------------------------------------------------------------------void
EliminarVertice(){
INFOVERTICE
Item;
VERTICE
*Vertice;
if
(CAB
==
NULL)
cout
<<
"Lista
vaca
\a";
else{

cout

<<

"\n\nDigite
etiqueta
del
v,rtice:
";
Item.NombreVertice
=
getche();
Vertice
=
EncontrarVerticeDelGrafo(Item);
if
(Vertice)
if(!Vertice->Cab)
//Se
elimina,
solo
si
no
tiene
adyacentes
EliminarVerticeDelGrafo(Vertice);
else{
cout<<"\n\nEste v,rtice tiene todava aristas. Favor eliminarlas primero";
getch();
}
else
{
cout << "\n\nNo encontrado en grafo un v,rtice con el nombre: "
<<
Item.NombreVertice;
getch();
}
}
}
//----------------------------------------------------------------------------------void
INFOVERTICE
VERTICE
if
(CAB
cout
<<
"Lista
cout

EncontrarVertice(){
Item;
*Vertice;
==
NULL)
vaca
\a";
else{
<<
"\n\nDigite
etiqueta
del
v,rtice
a
encontrar:
";
Item.NombreVertice
=
getche();
Vertice
=
EncontrarVerticeDelGrafo(Item);
if
(Vertice)
cout
<<
"\n\nEncontrado
en
grafo";
else
cout
<<
"\n\nNo
encontrado
en
grafo";
}
getch();

}
//
========================================================================
===
// A CONTINUACION LAS FUNCIONES PARA MANEJAR CADA ARISTA(SubLista enlazada)
//
========================================================================
===
ARISTA *InsertarArista (INFOARISTA Item, ARISTA *Cab, VERTICE *Destino){
ARISTA
*p,
*q,
*NuevoNodo;

if

(NuevoNodo
cout
<<

new
"No

ARISTA
hay
return

)
==
memoria

NULL
){
suficiente";
NULL;
}
//Se
insertar n
en
orden
ascendente
por
el
peso
de
la
arista
p
=
NULL;
q
=
Cab;
while
(q
!=
NULL
&&
Item.PesoArista
>
q->Info.PesoArista){
p
=
q;
q
=
q->Sig;
}
NuevoNodo->Info
=
Item;
NuevoNodo->Sig
=
q;
NuevoNodo->Ady
=
Destino;
if
(
p
==
NULL)
Cab
=
NuevoNodo;
//era
el
primero
de
la
lista
else
p->Sig
=
NuevoNodo;
//"caso
general"
return(Cab);
}
//----------------------------------------------------------------------------------ARISTA
*EliminarArista(ARISTA
*p,
ARISTA
ARISTA
if
(p
==
Cab
=
p->Sig;
//eliminado
el
primer
nodo
de
else
q
=
while
(q->Sig
!=
q
=
q->Sig
=

return
}
//----------------------------------------------------------------------------------ARISTA*
EncontrarArista(ARISTA
*Cab,
ARISTA
p
=
while
(p
&&
Destino
p
return
}
//-----------------------------------------------------------------------------------

VERTICE

!=
=

*Cab){
*q;
Cab)
la
lista
{
Cab;
p)
q->Sig;
p->Sig;
}
delete(p);
Cab;

*Destino){
*p;
Cab;
p->Ady)
p->Sig;
p;

void

ListarSubListaDeAristas(ARISTA
*Cab){
ARISTA
*p;
int
Adyacentes=0;
if
(!Cab)
cout
<<
"No
tiene
aristas
\a\n";
else
{
p
=
Cab;
cout
<<
"No.
Peso
Etiqueta
Destino\n";
while
(
p
){
cout
<<
setw(2)
<<
++Adyacentes
<<
":
"
<< setiosflags(ios::left) << setw(10) << p->Info.PesoArista
<< setw(15) << p->Ady->Info.NombreVertice << endl;
p
=
p->Sig;
}
}

}
//----------------------------------------------------------------------------------ARISTA
*CapturarSubLista(ARISTA
*Cab){
INFOARISTA
ItemArista;
INFOVERTICE
ItemVertice;
VERTICE
*Destino;
cout
<<
"\n\Etiqueta
v,rtice
de
destino:
";
cin
>>
ItemVertice.NombreVertice;
Destino=
EncontrarVerticeDelGrafo(ItemVertice);
if(Destino){
cout
<<
"\n\Peso
de
la
arista
a
insertar:
";
cin
>>
ItemArista.PesoArista;
ItemArista.NombreDestino
=
ItemVertice.NombreVertice;
Cab
=
InsertarArista(ItemArista,
Cab,
Destino
);
if
(
!Cab
){
cout << "\n\nNo se pudo insertar: se llen la memoria\a";
getch();
}
}
else{
cout
<<
"\n\aEste
destino
no
existe
en
el
grafo\a";
getch();
}
return
Cab;
}
//----------------------------------------------------------------------------------ARISTA*
BorrarSubLista(ARISTA
*Cab){
INFOVERTICE
Item;

ARISTA
*A;
VERTICE
*Destino;
if
(Cab
==
NULL)
cout
<<
"Lista
vaca
\a";
else
{
cout << "\n\nDigite etiqueta del nombre del
v,rtice de destino: ";
Item.NombreVertice
=
getche();
Destino=
EncontrarVerticeDelGrafo(Item);
if(Destino){ // Se encontr el destino, veamos si forma arista:
A
=
EncontrarArista(Cab,
Destino);
if
(A)
Cab
=
EliminarArista(A,
Cab);
else
{
cout
<<
"\n\nNo
encontrada
esta
arista";
getch();
}
}
else{
cout << "\n\nNo encontrado en grafo el v,rtice " << Item.NombreVertice;
getch();
}
}
return
Cab;
}
//----------------------------------------------------------------------------------void
EncuentraSubLista(ARISTA
INFOVERTICE
ARISTA
VERTICE
if
(Cab
cout
<<
"Lista

*Cab){
Item;
*p;
*Destino;
==
NULL)
vaca
\a";
else{
cout
<<
"\n\nDigite
Nombre
de
v,rtice
de
destino:
";
Item.NombreVertice
=
getch();
Destino=
EncontrarVerticeDelGrafo(Item);
if(Destino){
p
=
EncontrarArista(Cab,
Destino);
if
(p)
cout << "\n\nEncontrada esta arista y tiene el peso "
<<
p->Info.PesoArista;
else
cout << "\n\nNo encontrada arista al vertice " << Item.NombreVertice;
}

else
cout <<"\n\nNo existe en grafo vertice de destino "<<Item.NombreVertice;
}
getch();
}
//----------------------------------------------------------------------------------void
char
INFOVERTICE
VERTICE

MenuSubListaDeAristas(){
op;
Item;
*q;
if(CAB){
clrscr();
cout
<<
"Nombre
del
v,rtice
de
origen:
";
Item.NombreVertice
=
getche();
q
=
CAB;
while
(q
&&
Item.NombreVertice
!=
q->Info.NombreVertice)
q
=
q->Sig;
if
(!q){
cout << "No se encuentra ningun v,rtice de etiqueta: " << Item.NombreVertice;
getch();
}
else
do{
clrscr();
cout
<<
"Estas
son
las
aristas
del
v,rtice:
"
<<
q->Info.NombreVertice
<<
endl;
ListarSubListaDeAristas(q->Cab);
cout<< "\nSUBMENU DE ARISTAS: Insertar Borrar Encontrar ESCape: ";
op
=
toupper(getch());
switch
(op){
case
'I':
q->Cab=CapturarSubLista(q->Cab);
break;
case
'B':
q->Cab=BorrarSubLista(q->Cab);
break;
case
'E':
EncuentraSubLista(q->Cab);
break;
}
}
while
(op
!=
27);
}
else{
cout
<<
"No
hay
v,rtices
en
el
grafo\a";
getch();
}

}
//=======================================================================
====

void

GrabarSubListas(VERTICE

*V){
ARISTA
int

//

funcin

recursiva
*A;
n;
if
(
V
)
{
A
=
V->Cab;
n
=
0;
while(A)
{
//Cuenta
#
nodos
en
sublista
enlazada
de
aristas
n++;
A=A->Sig;
}
BufferArchivo.write((char *)&n, sizeof(n)); //Graba en disco #nodos(aristas)
A
=
V->Cab;
while(A)
{
BufferArchivo.write((char
*)&A->Info,
sizeof(A->Info));
A=A->Sig;
}
GrabarSubListas(V->Sig);
}

}
//----------------------------------------------------------------------------------void
Grabar(){
int
NumeroVertices=0;
BufferArchivo.open(NombreArch,
ios::out|ios::binary|ios::trunc);
if
(!BufferArchivo)
cout
<<
"Error
en
la
apertura
del
archivo
\a";
else{
VERTICE
*V;
V = CAB;
//Se cuentan y luego graban el nmero de v,rtices
while(V){
NumeroVertices++;
V
=
V->Sig;
}
BufferArchivo.write((char
*)&NumeroVertices,
sizeof(NumeroVertices));
V = CAB;
//Se graban a continuacin la info de todos los v,rtices
while(V){
BufferArchivo.write((char
*)&V->Info,
sizeof(V->Info));
V
=
V->Sig;
}
GrabarSubListas(CAB);//Se graba, recursivamente, info de todas las aristas
BufferArchivo.close();
}
}
//-----------------------------------------------------------------------------------

void

CargarLISTA_y_SubListas(){
INFOVERTICE Vertice; //registro que lee con info de cada v,rtice
VERTICE
*V,
*Destino;
int n; //nmero de nodos en cada sublista, lo lee desde disco cada vez
int
NumeroVertices=0;
INFOARISTA
Arista;
//registro
que
lee
con
info
de
cada
arista
CAB
=
NULL;
//Esta
variable
se
mantiene
global
BufferArchivo.open(NombreArch,ios::in|ios::binary);
if
(!BufferArchivo){
cout
<<
"No
se
puede
abrir
el
archivo
\a\n";
}
else
{
BufferArchivo.read((char
*)&NumeroVertices,
sizeof(NumeroVertices));
int i=0;//a continuacin lee desde disco, todos los v,rtices y los
//inserta
en
lista
enlazada
principal
while(i
<
NumeroVertices){
BufferArchivo.read(
(char
*)&Vertice,
sizeof(Vertice)
);
InsertarVerticeEnGrafo(Vertice);
i++;
}
//A continuacin se recorre la lista enlazada de v,rtices, ya en RAM y
//simult neamente se leen de disco, para cada vertice, el nmero de aristas
//y
luego cada una de ellas(insert ndolas en el lugar corrrepondiente)
V
=
CAB;
while(V){
BufferArchivo.read( (char *)&n, sizeof(n) ); //# nodos(aristas) en sublista
V->Cab=NULL;//ya
estaba
en
nulo,
no
es
necesario
for(i=0;
i<n;
i++){
BufferArchivo.read(
(char
*)&Arista,
sizeof(Arista));
//buscar
su
enlace
adyacente
NombreDestino
Destino
=
CAB;
while(Destino && Destino->Info.NombreVertice != Arista.NombreDestino)
Destino
=
Destino->Sig;
if(Destino)
V->Cab
=
InsertarArista(Arista,
V->Cab,
Destino);
else
return;//ERROR:dado como se grab en disco, es de esperar nunca ocurrir
}
V
=
V->Sig;
}
BufferArchivo.close();
}

//----------------------------------------------------------------------------------void
ListarGrafoComoTexto(){
if
(!CAB)
cout
<<
"Lista
vaca
\a\n";
else
{
VERTICE
*V
=
CAB;
ARISTA
*A;
cout << "ORIGEN
DESTINO
DISTANCIA ARISTA EN PIXELES\n";
while
(
V
){
if
(V->Cab){
A
=
V->Cab;
while
(
A
){
cout
<<
V->Info.NombreVertice
<< "
" << A->Ady->Info.NombreVertice
<< "
"<< setw(10) << A->Info.PesoArista << endl;
A
=
A->Sig;
}
}
else
cout
<<
setw(2)
<<
V->Info.NombreVertice
<<
endl;
V
=
V->Sig;
}
}
}
/****************************************************************************/
/* INICIO FUNCIONES PARA EL MANEJO DEL MOUSE CON INTERRUPCION 33 DEL
DOS
*/
/****************************************************************************/
int
IniciarMouse(int
&BotonMouse){
union
REGS
entra,sale;
entra.x.ax
=
0x0000;
int86(
0x33,
&entra,
&sale);
BotonMouse
=
sale.x.bx;
return
(
sale.x.ax
);
}
/****************************************************************************/
void
MostrarCursorMouse(void){
union
REGS
entra,
sale;
entra.x.ax
=
0x0001;
int86
(
0x33,
&entra,
&sale
);
}
/****************************************************************************/
void
EsconderCursorMouse(void){

union

REGS
entra.x.ax

int86(

entra,

sale;
0x0002;
&sale);

=
0x33,

&entra,

}
/****************************************************************************/
int
ClickMouseEnXY(
int
&x,
union
REGS
entra.x.ax
=
int86(
0x33,
&entra,
x
=
y
=

int

&y){
entra,sale;
0x0003;
&sale
);
sale.x.cx;
sale.x.dx;
return(sale.x.bx);

}
//**************************************************************************
void
CursorMouseAXY(
int
x,
int
y
){
union
REGS
entra,
sale;
entra.x.ax
=
0x0004;
entra.x.cx
=
x;
entra.x.dx
=
y;
int86(
0x33,
&entra,
&sale);
}
//---------------------------------------------------------------------------------void
ListarGrafoComoGrafico(int
Color){
char
Cad[2]="
";
if
(CAB){
VERTICE
*V;
ARISTA
*A;
setlinestyle(SOLID_LINE,
1,
3);
V
=
CAB;
while
(
V
){
EsconderCursorMouse();
setfillstyle(SOLID_FILL,
Color);
bar(V->Info.x-(AnchoVertice>>1),V->Info.y-(AnchoVertice>>1),
V->Info.x+(AnchoVertice>>1),V->Info.y+(AnchoVertice>>1));
Cad[0]=V->Info.NombreVertice;
setcolor(BLACK);
outtextxy(V->Info.x-3,
V->Info.y-2,
Cad);
MostrarCursorMouse();
A
=
V->Cab;
while
(
A
){
EsconderCursorMouse();
setcolor(YELLOW);
line(V->Info.x,
V->Info.y,
A->Ady->Info.x,
A->Ady->Info.y);

setfillstyle(SOLID_FILL,
Color);
bar(V->Info.x-(AnchoVertice>>1),
V->Info.y-(AnchoVertice>>1),
V->Info.x+(AnchoVertice>>1),
V->Info.y+(AnchoVertice>>1));
Cad[0]=V->Info.NombreVertice;
Cad[1]=NULL;
setcolor(BLACK);
outtextxy(V->Info.x-3,
V->Info.y-2,
Cad);
bar(A->Ady->Info.x-(AnchoVertice>>1),
A->Ady->Info.y-(AnchoVertice>>1),
A->Ady->Info.x+(AnchoVertice>>1),
A->Ady->Info.y+(AnchoVertice>>1));
Cad[0]=A->Ady->Info.NombreVertice;
Cad[1]=NULL;
outtextxy(A->Ady->Info.x-3,
A->Ady->Info.y-2,
Cad);
MostrarCursorMouse();
A
=
A->Sig;
}
V
=
V->Sig;
}
}
setlinestyle(SOLID_LINE,
1,
1);
}
//---------------------------------------------------------------------------------//---------------------------------------------------------------------------------//ALGORITMO DE RECORRIDO EN PROFUNDIDAD UTILIZANDO UNA PILA
//---------------------------------------------------------------------------------struct
Pila{
VERTICE
*V;
Pila
*Sig;
}
*Cima
=
NULL;
//----------------------------------------------------------------------------------void
InsertarEnPila(VERTICE
*V){
Pila
*Nuevo;
Nuevo
=
new
Pila;
Nuevo->V
=
V;
Nuevo->Sig
=
Cima;
Cima
=
Nuevo;
}
//----------------------------------------------------------------------------------VERTICE
*SacarDePila(){
VERTICE
*EnCima;
Pila
*p;
EnCima
=
Cima->V;

p
Cima

=
=

Cima;
Cima->Sig;
delete(p);
EnCima;

return
}
//----------------------------------------------------------------------------------void RecorridoEnProfundidad(){ //Al utilizar una Pila. Los nodos adyacentes
//estan siendo procesados de mayor arista primero a menor. Ya que la sublista
//esta clasificada en orden ascendente. Primero el menor, pero al colocarlos
//en Pila quedan al contrario. Es decir que esta prefiriendo el mayor.
//Para que tome el menor habria que modificar esta funcion y que lo haga
//recursivamente,
la
insercion
en
la
Pila
INFOVERTICE
Item;
VERTICE
*Origen,
*p,
*N;
ARISTA
*A;
if(CAB){
cout
<<
"\nDigite
la
etiqueta
del
v,rtice
de
origen:
";
cin
>>Item.NombreVertice;
Origen
=
EncontrarVerticeDelGrafo(Item);
if(!Origen)
cout
<<
"\nV,rtice
no
existe
en
el
Grafo\a";
else{
p
=
CAB;
while(p){
p->Info.Estado
=
1;
p
=
p->Sig;
}
InsertarEnPila(Origen);
Origen->Info.Estado
=
2;
cout
<<
endl;
while(Cima){
//Mientras
que
la
cola
no
est,
vaca
N
=
SacarDePila();
cout
<<
N->Info.NombreVertice
<<
"
";
N->Info.Estado
=
3;
A
=
N->Cab;
while(A){
if(A->Ady->Info.Estado
==
1){
InsertarEnPila(A->Ady);
A->Ady->Info.Estado
=
2;
}
A
=
A->Sig;
}
}

}
getch();
}
}
//---------------------------------------------------------------------------------//---------------------------------------------------------------------------------//ALGORITMO
DE
RECORRIDO
EN
ANCHURA
UTILIZANDO
UNA
COLA
//---------------------------------------------------------------------------------struct
Cola{
VERTICE
*V;
Cola
*Sig;
}
*Frente
=
NULL,
*Final=NULL,
*Q=NULL,
*q=NULL;
void
InsertarEnColas(VERTICE
*V){
Cola
*Nuevo;
Nuevo
=
new
Cola;
Nuevo->V
=
V;
Nuevo->Sig
=
NULL;
Nuevo->V->Info.d
=
Infinito;
//Se
necesitan
en
Alg.
Dijkstra
Nuevo->V->Predecesor
=
NULL;
//
en
otro
caso
no
importa
if(!Q){
//De
esta
cola
no
se
retiran
los
elementos
Q
=
q
=
Nuevo;
Nuevo->V->Info.d = 0; //Se necesitan en Alg. Dijkstra. Es el nodo fuente
}
else{
q->Sig
=
Nuevo;
q
=
Nuevo;
}
if(!Frente){
Frente
=
Final
=
Nuevo;
}
else{
Final->Sig
=
Nuevo;
Final
=
Nuevo;
}
}
//----------------------------------------------------------------------------------VERTICE
*AtenderFrenteDeCola(char
Dijkstra){
VERTICE
*AlFrente;
Cola
*p;
AlFrente
=
Frente->V;
if(Dijkstra=='N')
p
=
Frente;
Frente
=
Frente->Sig;

if(Dijkstra=='N')
delete(p);

//Si es 'S' no se deben borrar los valores


//frente avanzar hasta terminar, pero Q apunta
return

}
//----------------------------------------------------------------------------------int
RecorridoEnAnchura(char
INFOVERTICE
VERTICE
*Origen,
ARISTA
Frente
=
NULL,
Final=NULL,

en cola
al inicio
AlFrente;

Dijkstra){
Item;
*p,
*N;
*A;
Q=NULL,
q=NULL;
if(CAB){
cout
<<
"\nDigite
la
etiqueta
del
v,rtice
de
origen:
";
Item.NombreVertice
=
getche();
Origen
=
EncontrarVerticeDelGrafo(Item);
if(!Origen){
cout
<<
"\nV,rtice
no
Existe
en
el
Grafo\a";
return
0;
}
else{
p
=
CAB;
while(p){
p->Info.Estado
=
1;
p
=
p->Sig;
}
InsertarEnColas(Origen);
Origen->Info.Estado
=
2;
cout
<<
endl;
while(Frente){
//Mientras
que
la
cola
no
est,
vaca.
if(Dijkstra=='S')
N
=
AtenderFrenteDeCola('S');
else{
N
=
AtenderFrenteDeCola('N');
cout
<<
N->Info.NombreVertice
<<
"
";
}
N->Info.Estado
=
3;
A
=
N->Cab;
while(A){
if(A->Ady->Info.Estado
==
1){
InsertarEnColas(A->Ady);
A->Ady->Info.Estado
=
2;
}
A
=
A->Sig;
}

return
return

}
}
1;
}
0;

}
//---------------------------------------------------------------------------------//---------------------------------------------------------------------------------//ALGORITMO DE DIJKSTRA para el c lculo de trayectorias mnimas entre un
//v, rtice de origen y todos los dem es a los cuales se pueda llegar.
//---------------------------------------------------------------------------------void
AlgoritmoDeDijkstra(){
Cola *S;//Cola de prioridad ordenada por recorrido en anchura del grafo
//Desde el nodo fuente, hasta todos los que se pueda llegar
//Por
medio
de
los
adyacentes.
VERTICE
*U;
ARISTA
*A;
if(RecorridoEnAnchura('S')){
S
=
Q;
while(Q){
U = Q->V; //Se procede a atender el primer nodo de la cola de prioridad
Q
=
Q->Sig;
A
=
U->Cab;
while(A){ //Recorre cada una de las aristas del v,rtice U, "relajando"
if(A->Ady->Info.d
>
U->Info.d
+
A->Info.PesoArista){
A->Ady->Info.d
=
U->Info.d
+
A->Info.PesoArista;
A->Ady->Predecesor
=
U;
}
A
=
A->Sig;
}
}
//listado
del
conjunto
S
a
continuacin
clrscr();
cout
<<
"Vertice
Predecesor
Distancias
ms
cortas\n";
while(S){
cout
<<
S->V->Info.NombreVertice
<<
"
"
<< S->V->Predecesor->Info.NombreVertice << "
"
<<
setw(8)
<<
S->V->Info.d
<<
endl;
Q=S;
S
=
S->Sig;
delete(Q);
}
}
}

//---------------------------------------------------------------------------------//FIN
ALGORITMO
DE
DIJKSTRA.
//----------------------------------------------------------------------------------//***************************************************************************
//A CONTINUACION CODIGO NECESARIO PARA EL MANEJO DEL GRAFICO DEL GRAFO
//***************************************************************************
void
Icono1(int
x,
int
y){
setcolor(BLUE);
outtextxy(x+5,
y+6,
"Trazar
Arista");
}
//----------------------------------------------------------------------------void
Icono2(int
Xm,
int
Ym){
setcolor(BLUE);
outtextxy(Xm+AnchoVertice+1,
Ym+6,
"Dibujar
Vertice");
bar(Xm-(AnchoVertice>>1),
Ym-(AnchoVertice>>1)-EspacioGrafoYo,
Xm+(AnchoVertice>>1),
Ym+(AnchoVertice>>1)-EspacioGrafoYo
);
}
//----------------------------------------------------------------------------void
Icono3(int
x,
int
y){
setcolor(BLUE);
outtextxy(x+5,
y+6,
"Dijkstra,
etc..");
}
//----------------------------------------------------------------------------/**************************************************************************
*/
/*
Funcion
:
Ventana
*/
/*
Objetivo
:
Dibujar
un
ReCuadro
resaltado
o
undido.
*/
/**************************************************************************
*/
void
Ventana(int
x1,
int
y1,
int
x2,
int
y2,
int ColorArribaIzquierda, int ColorAbajoDerecha,
int
ColorFondo)
{
setfillstyle(1,
ColorFondo);
bar(x1,y1,
x2,y2);
setlinestyle(SOLID_LINE,0,
NORM_WIDTH);
setcolor(ColorArribaIzquierda);
line(x1,
y1,
x1,
y2);
line(x1,
y1,
x2,
y1);
setcolor(ColorAbajoDerecha);
line(x2,
y1,
x2,
y2);
line(x1,
y2,
x2,
y2);
}
/**************************************************************************
*/
/*
Funcion
:
Cursor
*/
/* Objetivo : Realiza recuadro, con una cadena centrada en su interior,
*/
/*
da a significar una de las opciones de un men
*/
/**************************************************************************
*/
void
Cursor(int
x,int
y,
int
pos,
int
Oprimido)
{
Icono[pos](x,
y);
setlinestyle(SOLID_LINE,
0,
NORM_WIDTH);
setcolor(DARKGRAY);
moveto(x,
y);
lineto(x+AnchoIcono,
y);

lineto(x+AnchoIcono,

y+AltoIcono);

lineto(x,
y+AltoIcono);
(!Oprimido)

if
line(x+1,
line(x+1,

y+1,
y+1,

line(x+AnchoIcono-1,
y+1,
line(x+1,
y+AltoIcono-1,
else
line(x+1,
line(x+1,

y+1,
y+1,

line(x+AnchoIcono-1,
y+1,
line(x+1,
y+AltoIcono-1,

lineto(x,

y);
{
setcolor(BLACK);
x+1,
y+AltoIcono-1);
x+AnchoIcono-1,
y+1);
setcolor(WHITE);
x+AnchoIcono-1,
y+AltoIcono-1);
x+AnchoIcono-1,
y+AltoIcono-1);
}
{
setcolor(WHITE);
x+1,
y+AltoIcono-1);
x+AnchoIcono-1,
y+1);
setcolor(BLACK);
x+AnchoIcono-1,
y+AltoIcono-1);
x+AnchoIcono-1,
y+AltoIcono-1);
}

}
/**************************************************************************
*/
void
GenerarIdentificadoresVertices(char
Letras[26]){
char c;
/*de la A a la Z del ASCII hay (90-65)+1=26 caracteres
Si se quiere trabajar con m es identificadores, de un solo carcter,
podrAmos hasta con 222, de la siguiente forma. ( Si m es entonces utilizar
m es de un carcter para cada identificador que se quiera tener.*/
//char Letras[222], c; //del ! al del ASCII hay (254-33)+1=222 caracteres
int
N=0,
i;
randomize();
do{
c = (char)random(26) + 'A';
//
c = (char)random(222) + '!';
i=0;
while(i
<
N
&&
c
!=
Letras
)
i++;
if(i==N)
Letras[N++]=c;
}
while(N<26);
//
}while(N<222);
Letras[N]
=
'\0';
}
/**************************************************************************
*/
VERTICE*
EncontrarXYVerticeDelGrafo(INFOVERTICE
Item,
int
Cercania){
VERTICE
*p;
p
=
CAB;
while
(p
&&
!(
( (Item.x >= (p->Info.x-Cercania*AnchoVertice) ) &&

return

p;

(Item.y >= (p->Info.y-Cercania*AnchoVertice) ) )


&& ( (Item.x <= (p->Info.x+Cercania*AnchoVertice) ) &&
(Item.y <= (p->Info.y+Cercania*AnchoVertice) ) )
) )
p
=
p->Sig;
//En caso que se encuentre, retorna la direccion del vertice

}
/**************************************************************************
void
Vertice(int
&Xm,
int
&Ym,
int
x,
y,
VERTICE
INFOVERTICE
char

*/
int
&Color){
Click=0;
*V;
Item;
Cad[2];
if(Ym<=EspacioGrafoYo)
CursorMouseAXY(Xm,
EspacioGrafoYo+1);
setviewport(EspacioGrafoXo, EspacioGrafoYo+1, EspacioGrafoXf, EspacioGrafoYf-1, 1);
delay(200);
do{
Click
=
ClickMouseEnXY(Xm,Ym);
if(
Click
)
{
if ( (Xm>=
PaletaXi && Xm<=PaletaXi+LargoPaleta*MaxColores) &&
(Ym>=
PaletaYi
&&
Ym<=PaletaYi+AltoIcono)
)
//Se
hizo
click
en
la
paleta
{
Color
=
(Xm-PaletaXi)/LargoPaleta;
setcolor(Color);
Click
=
0;
}
else{
Item.x=Xm;
Item.y=Ym;
if(!EncontrarXYVerticeDelGrafo(Item, 2)){//Encuentra si la posicin en
//pantalla, ya est ocupada, o no. Si no la encuentra ocupada, en la
//pantalla, entonces, lo dibujamos, le asignamos una letra y lo
//insertamos
en
la
lista
enlazada
principal.
EsconderCursorMouse();
setfillstyle(SOLID_FILL,
Color);
bar(Xm-(AnchoVertice>>1), Ym-(AnchoVertice>>1)-EspacioGrafoYo,
Xm+(AnchoVertice>>1), Ym+(AnchoVertice>>1)-EspacioGrafoYo );
Item.NombreVertice=IDVertices[N++];//Cuenta el nmero de v,rtices
Cad[0]=Item.NombreVertice;
Cad[1]='\0';
setcolor(BLACK); outtextxy(Xm-3, Ym-2-EspacioGrafoYo, Cad);
MostrarCursorMouse();
InsertarVerticeEnGrafo(Item);
}
else{sound(440);
delay(500);
nosound();}

while(Ym>EspacioGrafoYo
if(kbhit())
if(getch()==0)

}
/**************************************************************************
void
Arista(int
&Xm,
int
&Ym,
{
int
x,
y,
VERTICE
*U,
INFOVERTICE
INFOARISTA
char

&&

}
}
!kbhit());
getch();

*/
int
&Color)
Click=0;
*V;
Item;
item;
Cad[2];
if(Ym<=EspacioGrafoYo)
CursorMouseAXY(Xm,
EspacioGrafoYo+1);
setviewport(EspacioGrafoXo, EspacioGrafoYo+1, EspacioGrafoXf, EspacioGrafoYf-1, 1);
setwritemode(XOR_PUT);
setlinestyle(SOLID_LINE,
1,
3);
delay(200);
do{
Click
=
ClickMouseEnXY(Xm,Ym);
if(
Click
)
{
if ( (Xm>=
PaletaXi && Xm<=PaletaXi+LargoPaleta*MaxColores) &&
(Ym>=
PaletaYi && Ym<=PaletaYi+AltoIcono)) //hizo click en paleta
{
Color = (Xm-PaletaXi)/LargoPaleta;
setcolor(Color); Click = 0;
}
else{
Item.x
=
x
=
Xm;
Item.y
=
y
=
Ym;
U = EncontrarXYVerticeDelGrafo(Item, 1);//1 exactamente sobre dibujo
if(U){//Encuentra
vertice
de
origen
U
do{
EsconderCursorMouse();
line(x,y-EspacioGrafoYo,
Xm,Ym-EspacioGrafoYo);
MostrarCursorMouse();
delay(100);
EsconderCursorMouse();
line(x,y-EspacioGrafoYo,
Xm,Ym-EspacioGrafoYo);
MostrarCursorMouse();
}
while(ClickMouseEnXY(Xm,Ym)
&&
!kbhit());
if(!kbhit()){//Cancel
la
operacin
si
toc
el
teclado
Item.x=Xm;
Item.y=Ym;
V
=
EncontrarXYVerticeDelGrafo(Item,
1);
if(V){
//Encuentra
v,rtice
de
destino
EsconderCursorMouse();

line(U->Info.x,
U->Info.y-EspacioGrafoYo,
V->Info.x,
V->Info.y-EspacioGrafoYo);
setfillstyle(SOLID_FILL,
Color);
bar(U->Info.x-(AnchoVertice>>1),
U->Info.y-(AnchoVertice>>1)-EspacioGrafoYo,
U->Info.x+(AnchoVertice>>1),
U->Info.y+(AnchoVertice>>1)-EspacioGrafoYo);
Cad[0]=U->Info.NombreVertice;
Cad[1]=NULL;
setcolor(BLACK);
outtextxy(U->Info.x-3, U->Info.y-2-EspacioGrafoYo, Cad);
bar(V->Info.x-(AnchoVertice>>1),
V->Info.y-(AnchoVertice>>1)-EspacioGrafoYo,
V->Info.x+(AnchoVertice>>1),
V->Info.y+(AnchoVertice>>1)-EspacioGrafoYo);
Cad[0]=V->Info.NombreVertice;
Cad[1]=NULL;
outtextxy(V->Info.x-3, V->Info.y-2-EspacioGrafoYo, Cad);
MostrarCursorMouse();
item.PesoArista= sqrt(pow(V->Info.x - U->Info.x,2)+
pow(V->Info.y - U->Info.y,2));
item.NombreDestino
=
V->Info.NombreVertice;
U->Cab
=
InsertarArista(item,
U->Cab,
V);
break;
}
}
}
}
}
}
while(Ym>EspacioGrafoYo
&&
!kbhit());
setwritemode(COPY_PUT);
setlinestyle(SOLID_LINE,
1,
1);
if(kbhit())
if(getch()==0)
getch();
}
//----------------------------------------------------------------------------void
Iniciar(int
int
Manejador
=
DETECT,
initgraph(&Manejador,
&Modo,
Ventana(0, 0, 639, EspacioGrafoYo, WHITE, DARKGRAY,

Pos){
Modo;
"\\tc\\bgi");
LIGHTGRAY);
PosIcoX[0]=Xi;
Cursor(PosIcoX[0],
Yi,
0,
1);
for(int
i=1;
i<MaxIco;
i++){
PosIcoX
=
PosIcoX[i-1]
+
DeltaX;
Cursor(PosIcoX,
Yi,
i,
1);
}
Cursor(PosIcoX[Pos], Yi, Pos, 0); //Se activa opcin,Pos, del "men"

for(int

Color=0;
Color<16;
setfillstyle(SOLID_FILL,
bar(PaletaXi+Color*LargoPaleta,
PaletaXi+(Color+1)*LargoPaleta,

Color++){
Color);
PaletaYi,
PaletaYi+AltoPaleta);
}
setcolor(YELLOW);
rectangle(EspacioGrafoXo,
EspacioGrafoYf,
EspacioGrafoXf,
479);
setbkcolor(BLACK);
//ADVERTENCIA:
DEJAR
TODO
EL
TIEMPO
setbkcolor(BLACK)
activo
//en el escritorio colocar una barra del color deseado como fondo.
}
/**************************************************************************
void
char

*/
Submain(){
op;
restorecrtmode();
do{
clrscr();
ListarGrafoComoTexto();
//ListarVerticesDelGrafo();
cout<<"
Dijkstra
ESC";
switch
(
op
=
getch()
){
/*case
'v':
;
case
'V':
CapturarVertice('N');
break;
case
'b':
;
case
'B':
EliminarVertice();
break;
case
'e':
;
case
'E':
EncontrarVertice();
break;
case
'a':
;
case
'A':
MenuSubListaDeAristas();
break;
case
'p':
;
case
'P':
RecorridoEnProfundidad();
break;
case 'n': ;
case 'N': RecorridoEnAnchura('N'); getch(); break;*/
case
'd':
;
case
'D':
AlgoritmoDeDijkstra();
getch();break;
}
}
while
(op
!=
27);
clrscr();
setgraphmode(getgraphmode());

}
/**************************************************************************
*/
/*
Funcion
:
main
del
GrafoDirigido
*/
/* Objetivo : El programa inicia siempre por la funcin principal
*/
/**************************************************************************
*/
void
GrafoDirigido(){
int
PosIco=0, InvocarMenu=1, Click=0, Ym, Xm, Color=14, Redibujar=1;
char
Opcion;
if(!IniciarMouse(Click)){
outtextxy(10,10,"El
ratn
NO
est
instalado");
delay(2000);
return;
}
Click=0;
//unlink(NombreArch);
//Habilite
si
quiere
borrar
NombreArch

CargarLISTA_y_SubListas();
GenerarIdentificadoresVertices(IDVertices);
for(;;){
if(InvocarMenu){
if(Redibujar){
Iniciar(PosIco);
Redibujar=0;
if(CAB)
ListarGrafoComoGrafico(Color);
}
InvocarMenu
=
0;
}
setviewport(0,
0,
639,
479,
1);
MostrarCursorMouse();
do{
Click
=
ClickMouseEnXY(Xm,Ym);
if(
(Xm>=
Xi
&&
Xm<=PosIcoX[MaxIco-1]+AnchoIcono)
&&
(Ym>=
Yi
&&
Ym<=Yi+AltoIcono)
){
int
i=0;
while(i<MaxIco && !(Xm>PosIcoX && Xm<PosIcoX+AnchoIcono))
i++;
if(i<MaxIco){// est el cursor del mouse dentro de recuadro del men
if(Click)//
Se hizo "click" en recuadro del men
InvocarMenu
=
1;
if(i!=PosIco){
EsconderCursorMouse();
Cursor(PosIcoX[PosIco], Yi, PosIco, 1);//PosIco actual se inactiva
PosIco=i;
Cursor(PosIcoX[PosIco],
Yi,
PosIco,
0);
MostrarCursorMouse();
}
}
}
if(
Click
&&
//Se
hizo
click
en
la
paleta
(Xm>=
PaletaXi && Xm<=PaletaXi+LargoPaleta*MaxColores) &&
(Ym>=
PaletaYi
&&
Ym<=PaletaYi+AltoIcono)
)
{
Color
=
(Xm-PaletaXi)/LargoPaleta;
Click
=
0;
}
if(!InvocarMenu
&&
Click){
//Se
hizo
click
en
el
escritorio
Click=0;
}
}
while
(!kbhit()
&&
!Click);

if(InvocarMenu

case
case
case

if(Opcion!=0){

Opcion

&&

Click==1){

//Mouse
setcolor(Color);
switch(PosIco){
0:
Arista(Xm,
Ym,
Color);
break;
1:
Vertice(Xm,
Ym,
Color);
break;
2:
Submain();
Redibujar=1;
break;
}
Click=0;
}
else{
//Teclado
Opcion
=
getch();
//tecla
con
cdigo
ASCII
switch(Opcion){
case
27:
Grabar();
return;
}
}
else{
getch();
//lee
segundo
byte
de
tecla
switch(Opcion){
case
45:
return;
}
}
}
}

}
//******************************************************************************
//
FIN
DE
LOS
ALGORITMOS
DEL
GRAFO
DIRIGIDO
//******************************************************************************
/****************************************************************************/
/*A CONTINUACION EL CODIGO NECESARIO PARA EL MANEJO DEL MENU
PRINCIPAL
*/
/****************************************************************************/
/****************************************************************************/
/*
Funcin
:
BarColor
*/
/* Objetivo
:
Esta funcion se encarga de hacer una barra
*/
/*
en la pantalla, de un color dado y un patrn.
*/
/****************************************************************************/
void
BarraDeColor(int
x1,int
y1,int
x2,int
y2,int
Patron,
int
Color){
int
ColorAnterior
=
getcolor();
setfillstyle(Patron,Color);
bar(x1,y1,x2,y2);
setcolor(ColorAnterior);
}

/****************************************************************************/
/*
Funcin
:
RecuadroVentana
*/
/*
Objetivo
:
Dibujar
un
ReCuadro
resaltado
o
undido.
*/
/****************************************************************************/
void
RecuadroVentana(int
X1,int
Y1,int
X2,int
Y2,int
ArbAbj){
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
if(ArbAbj
==
1)
setcolor(DARKGRAY);
else
setcolor(WHITE);
line(X1,
Y1,
X1,
Y2);
line(X1,
Y1,
X2,
Y1);
if(ArbAbj
==
1)
setcolor(WHITE);
else
setcolor(DARKGRAY);
line(X2,
Y1,
X2,
Y2);
line(X1,
Y2,
X2,
Y2);
}
/****************************************************************************/
/* FUNCION
: RealzaCuadro
*/
/* OBJETIVO : Muestra un rectangulo en pantalla, el cual significa
*/
/*
una
de
las
opciones
de
un
men.
*/
/****************************************************************************/
void
RealzaCuadro(int
x1,int
y1,int
x2,int
y2,int
color1,int
color2){
setbkcolor(BLACK);
setcolor(color1);
line(x1,y1,x2,y1);
line(x1,y1,x1,y2);
setcolor(color2);
line(x1,y2,x2,y2);
line(x2,y2,x2,y1);
}
/****************************************************************************/
void RealzarCursor(int x1,int y1,int x2,int y2,int Color1,int Color2,int Color3){
setcolor(Color1);line(x1,y1,x2,y1);
line(x1,y1,x1,y2);
setcolor(Color2);line(x1,y2,x2,y2);
line(x2,y2,x2,y1);
setcolor(Color3);line(x1+1,y1+1,x2-1,y1+1);line(x1+1,y1+1,x1+1,y2-1);
line(x1+1,y2-1,x2-1,y2-1);line(x2-1,y2-1,x2-1,y1+1);
setfillstyle(1,Color3);
floodfill(x1+5,y1+5,Color3);
setcolor(Color2);
line(x1+1,y2-1,x2-1,y2-1);
line(x2-1,y2-1,x2-1,y1+1);
}
/****************************************************************************/
/*
Funcin
:
Cursor
*/
/* Objetivo : Realiza recuadro, con una cadena centrada en su interior,
*/
/****************************************************************************/
void
Cursor(int
X,
int
Y,
int
LargoCuadro,
char
*Cad,
int Col1,int Col2,int Col3,int Col4,int Col5,int Oprimido){
int
AltoCuadro;

char

c[3];
EsconderCursorMouse();
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
AltoCuadro=textheight(Cad)
+
10;
if(LargoCuadro==0)
LargoCuadro
=
X
+
textwidth(Cad)
+
10;
else
LargoCuadro
=
X
+
LargoCuadro
+
10;
if(!Oprimido){
BarraDeColor(X,Y,LargoCuadro,Y+AltoCuadro,SOLID_FILL,Col1);
RecuadroVentana(X,Y,LargoCuadro,Y+AltoCuadro,1);
setcolor(Col3);
}
else{
BarraDeColor(X,Y,LargoCuadro,Y+AltoCuadro,SOLID_FILL,Col2);
RecuadroVentana(X,Y,LargoCuadro,Y+AltoCuadro,1);
setcolor(Col4);
}
outtextxy(X+5,Y+5,Cad);
setcolor(Col5);
c[0]
=
Cad[0];
c[1]
='\0';
outtextxy(X+5,Y+5,c);
MostrarCursorMouse();
}
/**************************************************************************/
/*
Funcin
:
PulsadoCuadro
*/
/* Objetivo : Realiza Cursor con una cadena centrada en su
*/
/*
interior
y
da
la
sensacion
de
que
se
oprime.
*/
/**************************************************************************/
void
UndidoCursor(int
X,int
Y,int
LargoCadenaMayor,
char *Cad, int Col1, int Col2, int Col3, int Col4, int Col5){
const
NoActual=0,
Actual=1;
EsconderCursorMouse();
Cursor(X, Y, LargoCadenaMayor,Cad, Col1, Col2, Col3, Col4, Col5, NoActual );
delay(100);
Cursor(X, Y, LargoCadenaMayor,Cad, Col1, Col2, Col3, Col4, Col5, Actual );
delay(100);
Cursor(X, Y, LargoCadenaMayor,Cad, Col1, Col2, Col3, Col4, Col5, NoActual);
MostrarCursorMouse();
}
/*
**************************************************************************/
void
RecuadroCursor(int
x1,int
y1,int
x2,int
y2,int
Color1,int
Color2){
setbkcolor(7);
setcolor(Color1);
line(x1,y1,x2,y1);
line(x1,y1,x1,y2);

line(x1,y2,x2,y2);

setcolor(Color2);
line(x2,y2,x2,y1);

}
/****************************************************************************/
/*
Funcin
:
CentrarXCad
*/
/* Objetivo : Esta funcin se encarga de Escribir una cadena
*/
/*
centrada
en
la
pantalla
en
modo
gr fico
*/
/****************************************************************************/
void
CentrarXCad(int
Fila,
char
*Cad){
int
largo;
largo
=
textwidth(Cad);
outtextxy((getmaxx()-largo)/2,Fila,Cad);
}
/****************************************************************************/
void
PresentacionPantalla(){
EsconderCursorMouse();
cleardevice();
setcolor(WHITE);
rectangle(0,0,getmaxx(),getmaxy());
RealzarCursor(170,110,480,370,WHITE,DARKGRAY,LIGHTGRAY);
RecuadroCursor(16,10,624,450,WHITE,DARKGRAY);
RecuadroCursor(55,60,585,400,DARKGRAY,WHITE);
RecuadroCursor(58,63,582,397,WHITE,DARKGRAY);
setcolor(11);
for(int
i=170;i<480;i+=5)
line(325,240,i,110);
setcolor(14);
for(i=170;i<479;i+=3)
line(170,110,i,368);
setcolor(15);
for(int
j=110;j<379;j+=20)
line(325,240,478,j);
setcolor(RED);
CentrarXCad(190,"Elvin
Gonzalez");
setcolor(BLUE);
CentrarXCad(220,"Alexander
Caballero");
MostrarCursorMouse();
}
/*
************************************************************************
*/
/*
Funcin
:
EscribirComentarioOpcionMenu
*/
/* Objetivo : Muestra avisos correspondientes a opciones del men
*/
/*
************************************************************************
*/
void
EscribirComentarioOpcionMenu(char
*Comentario){
RealzarCursor(75,410,570,430,DARKGRAY,WHITE,
BLUE);
setfillstyle(SOLID_FILL,BLUE);
bar(80,getmaxy()-65,getmaxx()-75,getmaxy()-55);
settextstyle(DEFAULT_FONT,0,1);
setcolor(WHITE);
CentrarXCad(getmaxy()-63,
Comentario);
}
/*
***********************************************************************
*/
/*
Funcin
:
AMAYUSCULA
*/
/* Objetivo : Convierte un caracter en minscula a mayscula.
*/
/*
***********************************************************************
*/

char

AMayuscula(char
if(c>=97

&&
c
return

}
/*
/*
/*
void

-=

***********************************************************************
FUNCION
PRINCIPAL
***********************************************************************

c){
c<=122)
(97-65);
c;

*/
*/
*/
main(){
const
Der=77,
Izq=75,
Esc=27,
Entrar=13,
MaxOp=2,
NoActual=0,
Actual=1,
DeMas=12;
int Pos=0, Invocar=1,
i, Fila=25, Xm, Ym,
Click, PosX[MaxOp], AnchoCursor=0;
char
Tecla;
char
Op[MaxOp][30]
=
{"Dijkstra",
"Salir"};
char Comentario[MaxOp][80]={"Algoritmo Dijkstra","Terminar el programa. ESC" };
int
Manejador
=
DETECT,
Modo;
initgraph
(&Manejador,
&Modo,
"\\tc\\bgi");
if(!IniciarMouse(Click)){
outtextxy(10,10,"El
ratn
NO
est
instalado");
delay(2000);
exit(1);
}
setfillstyle(SOLID_FILL,
0);
settextstyle(DEFAULT_FONT,HORIZ_DIR,0);
settextjustify(LEFT_TEXT,TOP_TEXT);
for(i=0;i<MaxOp;i++)
AnchoCursor
+=
textwidth(Op)+DeMas;
PosX[0]
=
(getmaxx()-AnchoCursor)/2;
for(i=1;i<MaxOp;i++)
PosX
=
PosX[i-1]+textwidth(Op[i-1])+DeMas;
for(;;){
if(Invocar){
setbkcolor(LIGHTGRAY);
cleardevice();
PresentacionPantalla();
for(i=0;
i<MaxOp;
i++)
Cursor(PosX,Fila,0, Op, LIGHTGRAY, CYAN, WHITE, WHITE, RED, NoActual);
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, WHITE, RED, Actual);
EscribirComentarioOpcionMenu(Comentario[Pos]);
Invocar
=
0;
Xm=PosX[Pos];
Ym=Fila+DeMas;
CursorMouseAXY(Xm,
Ym);
}
MostrarCursorMouse();
do{

Click
if(Ym>=Fila

ClickMouseEnXY(Xm,Ym);
&&
Ym<=Fila+textheight("H")+10){
i=0;
while(i<MaxOp && !(Xm>PosX && Xm<PosX+textwidth(Op)+DeMas))
i++;
if(i<MaxOp){// est el cursor del mouse dentro de recuadro del men
if(Click)//
Se
hizo
"click"
en
recuadro
del
men
Invocar
=
1;
if(i!=Pos){
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, WHITE,
RED,NoActual);
Pos=i;
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, WHITE,
RED,Actual);
EscribirComentarioOpcionMenu(Comentario[Pos]);
}
}
}
}
while
(!kbhit()
&&
!Click);
if(!Click){
//Se
digit
del
teclado
Tecla
=
getch();
if(Tecla == 0 ){ //tecla, o combinacin de teclas de secuencia de escape
Tecla
=
getch();
switch(Tecla){
case
Der:
EscribirComentarioOpcionMenu(Comentario[Pos]);
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, WHITE,
RED,NoActual);
Pos++;
if(Pos
==
MaxOp)
Pos=0;
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, WHITE,
RED,Actual);
EscribirComentarioOpcionMenu(Comentario[Pos]);
break;
case
Izq:
EscribirComentarioOpcionMenu(Comentario[Pos]);
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, WHITE,
RED,NoActual);
Pos--;
if(Pos
==
-1)
Pos
=
MaxOp-1;
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, WHITE,
RED,Actual);
EscribirComentarioOpcionMenu(Comentario[Pos]);

break;
case
45:
exit(0);
//
Alt-X
case
59:
//F1
break;
}
}
else{
//Se digit una tecla del teclado con cdigo ASCII
if(Tecla==Esc)
return;
if(Tecla==Entrar)
Invocar
=
1;
else{
Tecla=AMayuscula(Tecla);
i=0;
while(Tecla!=Op[0]
&&
i<MaxOp)
i++;
if(i<MaxOp){//
Se
digit
letra
inicial
de
opcin
if(i!=Pos){
//letra inicial es de una opcion diferente
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, WHITE,
RED,NoActual);
Pos=i;
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, WHITE,
RED,Actual);
EscribirComentarioOpcionMenu(Comentario[Pos]);
}
Invocar=1;
}
}
}
}
if(Invocar){
EsconderCursorMouse();
UndidoCursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE, 15, RED);
graphdefaults();
switch(Pos){
/*case
0:
ARBOL
*Raiz=NULO;
Raiz=CapturaDeExpresiones(Raiz);
EliminarSubArbolDeMemoria(Raiz);
getch();
break;
*/
case
0:
GrafoDirigido();
case
1:
return;
}

Click=0;
//

}
/****************************************************************************/
//FIN
DEL
/****************************************************************************/

MostrarCursorMouse();
graphdefaults();
}
Tecla=0;
for(;;);

PROGRAMA

Usuario

Sabes que quizs


me sirva, pero es que tengo un grafo dibujado
para el grafo G haga el algoritmo de los caminos mnimos hasta el tercer paso(no se cuales
pasos)
Haga el algoritmo de dijkstra para hallar los caminos mnimos entre A y todos los dems
vrtices
del
grafo
efecte el recorrido del grafo mediante bsqueda

Vous aimerez peut-être aussi