0% found this document useful (0 votes)
88 views

Kruskal

The document describes a mini project that graphically implements Kruskal's algorithm for finding the minimum spanning tree of a graph. It includes sections on the team members, system requirements, an introduction to Kruskal's algorithm, the functional description and pseudocode, an example, and plans for testing and implementation.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
88 views

Kruskal

The document describes a mini project that graphically implements Kruskal's algorithm for finding the minimum spanning tree of a graph. It includes sections on the team members, system requirements, an introduction to Kruskal's algorithm, the functional description and pseudocode, an example, and plans for testing and implementation.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 39

Graphical

Implementation
of
Kruskal's Algorithm

A Mini Project
Submitted
In
Partial Fulfillment of the Requirements
For the degree of

Bachelor of Technology

By

Aftab Khan
Gaurav Srivastava
Gaurav Tomar

B.Tech (CS)
5th Semester

(Session: 2009-2010)

Department of Computer Science & Engineering


SHIVDAN SINGH INSTITUTE OF TECHNOLOGY & MANAGEMENT
ALIGARH

December 2009
SHIVDAN SINGH INSTITUTE OF TECHNOLOGY & MANAGEMENT
Approved by AICTE & Affiliated to U.P. Technical University, Lucknow
10 km stone, Aligarh-Mathura Road, P.O. Mahua, Aligarh (U.P)

_____________________________________________________________

Certificate

This is to certify that the mini project entitled “ Graphical


Implementation of Kruskal’s algorithm ” has been carried out
by Aftab Khan, Gaurav Srivastav and Gaurav Tomar, under
my guidance and supervision during the academic session
2009-2010 in partial fulfillment of the requirement for Degree
of Bachelor of Technology in Computer Science &
Engineering.

Date:

Mr. Santosh Maurya Mr. Ranjeet Rai


(Head of Department) (Project Guide)
(Computer Science & Engg.) (Computer Science & Engg.)
Acknowledgement

Before we proceed further, we wish to spend some time in expressing


our gratitude to all those who have been involved in guiding us and helping
out during our entire project. We express my deep sense of gratitude and
indebtedness to our guide Mr. Santosh Maurya (head of department of
computer science) for liberal and whole hearted support to us in completing
this project.
We feel most delighted to make special mention of Mr. Ranjeet Rai
who helped us immensely in sorting out of difficulties during the project
work. Finally, we would like to thank all of my friend and colleagues who
zealously encouraged us and provided full support whenever needed.

Aftab Khan
Gaurav Srivastav
Gaurav Tomar
Table of Content

Team description
• Members
• Team leader
• Work distribution
System requirements
• Hardwares
• Softwares
Kruskal’s algorithm
Introduction
Functional description
• Performance
• Pseudocode/algorithm
• Proof of correctness
• Spanning tree
• Minimality
• Example
Design details
Coding details
Testing plan
Limitation
Source code
References
Team description

Members
Aftab Khan 0600710006
Gaurav Srivastava 0600710033
Gaurav Tomar 07007100

Team Leader
Gaurav Srivastava

Work distribution
The algorithms were coded in C++ (using Borland’s TurboC++
compiler), The work was divided as follows :
Each member coded the kruskal’s algorithm implementation in C++
graphics. For the graphical side of the project, the team was split up in two -
one member coded the GUI (using TurboC++ Graphics Library) while the
other coded the main algorithm for the project.
System requirement

Hardware

Intel’s x86 based CPU like Pentium 4,


RAM 128 MB is sufficient,
40 GB Hard disk is more than sufficient,
Standard 104 keys keyboard,
USB or PS/2 Mouse.

Software

Microsoft Windows operating system like Win98, WinXP but non-vista,


Borland’s TurboC++ compiler,
Egavga.bgi file in the folder with main executable,
Notepad.
Kruskal's algorithm

Introduction
Kruskal's algorithm is an algorithm in graph theory that finds a
minimum spanning tree for a connected weighted graph. This means it finds
a subset of the edges that forms a tree that includes every vertex, where the
total weight of all the edges in the tree is minimized. If the graph is not
connected, then it finds a minimum spanning forest (a minimum spanning
tree for each connected component). Kruskal's algorithm is an example of a
greedy algorithm.

It works as follows:

• create a forest F (a set of trees), where each vertex in the graph is a


separate tree
• create a set S containing all the edges in the graph
• while S is nonempty
o remove an edge with minimum weight from S
o if that edge connects two different trees, then add it to the
forest, combining two trees into a single tree
o otherwise discard that edge.

At the termination of the algorithm, the forest has only one component and
forms a minimum spanning tree of the graph.

Functional description

Performance
Where E is the number of edges in the graph and V is the number of
vertices, Kruskal's algorithm can be shown to run in O(E log E) time, or
equivalently, O(E log V) time, all with simple data structures. These running
times are equivalent because:

• E is at most V2 and logV2 = 2logV is O(log V).


• If we ignore isolated vertices, which will each be their own
component of the minimum spanning forest, V ≤ E+1, so log V is
O(log E).

We can achieve this bound as follows: first sort the edges by weight
using a comparison sort in O(E log E) time; this allows the step "remove an
edge with minimum weight from S" to operate in constant time. Next, we
use a disjoint-set data structure to keep track of which vertices are in which
components. We need to perform O(E) operations, two 'find' operations and
possibly one union for each edge. Even a simple disjoint-set data structure
such as disjoint-set forests with union by rank can perform O(E) operations
in O(E log V) time. Thus the total time is O(E log E) = O(E log V).

Provided that the edges are either already sorted or can be sorted in linear
time (for example with counting sort or radix sort), the algorithm can use
more sophisticated disjoint-set data structures to run in O(E α(V)) time,
where α is the extremely slowly-growing inverse of the single-valued
Ackermann function.

Pseudocode/algorithm
1. function Kruskal(G)
2. Define an elementary cluster C(v) ← {v}.
3. Initialize a priority queue Q to contain all edges in G,
using the weights as keys.
4. Define a forest T ← Ø //T will ultimately contain
the edges of the MST
5. // n is total number of vertices
6. while T has fewer than n-1 edges do
7. // edge u,v is the minimum weighted route from/to v
8. (u,v) ← Q.removeMin()
9. // prevent cycles in T. add u,v only if T does not already
contain a path between u and v.
10. // the vertices has been added to the tree.
11. Let C(v) be the cluster containing v, and
let C(u) be the cluster containing u.
13. if C(v) ≠ C(u) then
14. Add edge (v,u) to T.
15. Merge C(v) and C(u) into one cluster, that is, union C(v) and C(u).
16. return tree T
Proof of correctness
The proof consists of two parts. First, it is proved that the algorithm
produces a spanning tree. Second, it is proved that the constructed spanning
tree is of minimal weight.

Spanning tree

Let P be a connected, weighted graph and let Y be the subgraph of P


produced by the algorithm. Y cannot have a cycle, since the last edge added
to that cycle would have been within one subtree and not between two
different trees. Y cannot be disconnected, since the first encountered edge
that joins two components of Y would have been added by the algorithm.
Thus, Y is a spanning tree of P.

Minimality

We show that the following proposition P is true by induction: If F is the


set of edges chosen at any stage of the algorithm, there is some minimum
spanning tree that contains F.

• Clearly P is true at the beginning, when F is empty: any minimum


spanning tree will do.
• Now assume P is true for some non-final edge set F and let T be a
minimum spanning tree that contains F. If the next chosen edge e is
also in T, then P is true for F+e. Otherwise, T+e has a cycle C and
there is another edge f that is in C but not F. Then T-f+e is a tree, and
its weight is not more than the weight of T since otherwise the
algorithm would choose f in preference to e. So T-f+e is a minimum
spanning tree containing F+e and again P holds.
• Therefore, by the principle of induction, P holds when F has become a
spanning tree, which is only possible if F is a minimum spanning tree
itself.
Example:

This is our original graph. The numbers near the arcs indicate their weight.
None of the arcs are highlighted.

fig. 1

AD and CE are the shortest arcs, with length 5, and AD has been arbitrarily
chosen, so it is highlighted.

fig. 2

CE is now the shortest arc that does not form a cycle, with length 5, so it is
highlighted as the second arc.
fig. 3

The next arc, DF with length 6, is highlighted using much the same method.

fig. 4

The next-shortest arcs are AB and BE, both with length 7. AB is chosen
arbitrarily, and is highlighted. The arc BD has been highlighted in red,
because there already exists a path (in green) between B and D, so it would
form a cycle (ABD) if it were chosen.

fig. 5

The process continues to highlight the next-smallest arc, BE with length 7.


Many more arcs are highlighted in red at this stage: BC because it would
form the loop BCE, DE because it would form the loop DEBA, and FE
because it would form FEBAD.
fig. 6

Finally, the process finishes with the arc EG of length 9, and the minimum
spanning tree is found.

fig. 7

Design details

Our program is designed to be more user friendly using the both


mouse and keyboard based interface implementation. The entire program
configurations, and algorithms implementation visualise through a simple-
to-use interface. The user may deside the no. of edges, vertices and their
desire weights sequentially, and each vertices can be directly positioned on
the graphical window with the help of mouse button control. At the end of
the runtime, a graph of the performances of all the algorithms is generated
and logged.

Coding details

Coding all these graphical user interface for the implementation of


algorithms have taught us that every problem has different approaches ,each
of which have their own pros and cons .We have seen that for our problem
admits many conceptually different solutions. Standard library functions
along with graphics routine, are interfaced together with the main algorithm
in such a manner that a proper affect must be maintained. Borland’s graphics
interface file “egavga.bgi” must be in the parent folder otherwise error
should occur.
Important source files for the program are kruskal.cpp and two header
files input.h and mouse.h for mouse interface implementation.

Testing plan

Various sequences of requests will be created to se how various


algorithms perform under different conditions. During the testing of our
algorithms we realized how certain algorithms fail under certain test
cases and have learnt how to engineer such cases. As an example the greedy
algorithm which performs extremely well most of the time can be easily
made to fail.

Limitation

Currently the no. of vertices and edges are limited to 10 and 15


respectively. Little bit slow execution on older machine. Takes few moments
in cost estimation for greater no. of components.
Source code: kruskal.cpp
# include <iostream.h>
# include <graphics.h>
# include <string.h>
# include <stdlib.h>
# include <conio.h>
# include <math.h>

# include "Mouse.h"
# include "Input.h"

# define MAX_VERTICES 10
# define MAX_EDGES 15

class Vertex
{
public:
int x;
int y;
int label;

private:
char Label[5];

public:
Vertex( ) { }
~Vertex( ) { }

void SetVertex(const int,const int,const int);


void ShowVertex( );

const int Hit( );


};
class Edge
{
public:
int weight;

Vertex V1;
Vertex V2;
private:
char Weight[5];

public:
Edge( ) { }
~Edge( ) { }

void SetEdge(const Vertex,const Vertex,const int);


void ShowEdge( );
};
void Vertex::SetVertex(const int _x,const int _y,const int _label)
{
x=_x;
y=_y;
label=_label;
itoa((label+1),Label,10);
}
void Vertex::ShowVertex( )
{
HideMouseCursor( );
setcolor(1);
setfillstyle(1,1);
pieslice(x,y,0,360,10);
setcolor(9);
circle(x,y,10);
circle(x,y,11);
setcolor(15);
settextstyle(2,0,4);
if(label<9)
outtextxy((x-2),(y-6),Label);
else if(label>=9)
outtextxy((x-5),(y-6),Label);
ShowMouseCursor( );
}

const int Vertex::Hit( )


{
int _x=0;
int _y=0;
GetMousePosition(&_x,&_y);
if(_x>=(x-10) && _x<=(x+10) && _y>=(y-10) && _y<=(y+10))
{
double d=sqrt(( powl((_x-x),2) + pow((_y-y),2) ));
if(d<=10)
return 1;
}
return 0;
}
void Edge::SetEdge(const Vertex _V1,const Vertex _V2,const int _weight)
{
V1=_V1;
V2=_V2;

weight=_weight;

itoa(weight,Weight,10);
}
void Edge::ShowEdge( )
{
HideMouseCursor( );

setlinestyle(0,0,3);

setcolor(1);
line(V1.x,V1.y,V2.x,V2.y);

setlinestyle(0,0,0);

V1.ShowVertex( );
V2.ShowVertex( );

int x=(((V1.x+V2.x)/2)-6);
int y=(((V1.y+V2.y)/2)-8);

setcolor(11);
settextstyle(2,0,7);
outtextxy(x,y,Weight);
outtextxy((x+1),y,Weight);
outtextxy((x+1),(y+1),Weight);

ShowMouseCursor( );
}
void PrintText(const int x,const int y,const int number,const int
color=15)
{
char Number[10]={NULL};

itoa(number,Number,10);

moveto(x,y);

setcolor(color);
settextstyle(2,0,4);
outtext(Number);
}
int main( )
{
int driver=VGA;
int mode=VGAHI;
int error_code;
initgraph(&driver,&mode,"..\\Bgi");
error_code=graphresult( );
if(error_code!=grOk)
{
restorecrtmode( );
textmode(BW80);
clrscr( );

cout<<" \n Fatal Error : Graphic Driver not initialized"<<endl;


cout<<" Error Reason : "<<grapherrormsg(error_code)<<endl;
cout<<" \n Press any key to exit...";

getch( );
exit(1);
}
cleardevice( );
setcolor(15);
rectangle(5,5,635,32);
rectangle(5,35,635,455);
rectangle(5,458,635,476);

setfillstyle(1,7);
bar(6,6,634,31);

setfillstyle(1,8);
bar(6,459,634,475);
bar(23,80,180,83);

settextstyle(2,0,7);
setcolor( 9);
outtextxy(119,6,"***** Kruskal's Algorithm *****");
outtextxy(120,6,"***** Kruskal's Algorithm *****");
outtextxy(120,7,"***** Kruskal's Algorithm *****");

setcolor(11);
outtextxy(24,60,"Prerequisites:");
outtextxy(25,60,"Prerequisites:");
outtextxy(25,61,"Prerequisites:");

int vertices=0;
int edges=0;

setcolor(15);
settextstyle(2,0,4);
outtextxy(25,96,"Enter the Total Number of Vertices ( 1-10 ) = ");

vertices=atoi(GetInput(295,95,2,15,0));

vertices=((vertices<1)?1:vertices);
vertices=((vertices>10)?10:vertices);

setcolor(15);
settextstyle(2,0,4);
outtextxy(25,115,"Enter the Total Number of Edges ( 1-15 ) = ");

edges=atoi(GetInput(295,114,2,15,0));

edges=((edges<0)?0:edges);
edges=((edges>15)?15:edges);

setfillstyle(1,8);
bar(23,380,115,383);

setcolor(11);
settextstyle(2,0,7);
outtextxy(24,360,"Read Me:");
outtextxy(25,360,"Read Me:");
outtextxy(25,361,"Read Me:");

setcolor(15);
settextstyle(2,0,4);
outtextxy(25,390,"* Press LeftMouseKey where you want to place a
Vertex.");
outtextxy(25,405,"* To draw an Edge, Click on a Vertex and Drag
the Mouse Pointer to the other Vertex and Release the");
outtextxy(25,418," LeftMouseKey, then enter the Weight of the
Edge.");

setcolor(14);
settextstyle(2,0,4);
outtextxy(15,461,"Press any Key to Continue...");

getch( );

setfillstyle(0,1);
bar(6,36,634,454);

setfillstyle(1,8);
bar(6,459,634,475);

setcolor(14);
settextstyle(2,0,4);
outtextxy(15,461,"Mark the Vertices Positions...");

Vertex V[MAX_VERTICES];
Edge E[MAX_EDGES];

InitMouse( );
ShowMouseCursor( );
SetMousePosition(320,240);
SetMouseRange(20,50,620,440);

int x;
int y;

for(int count=0;count<vertices;count++)
{
while(!LeftMouseKeyPressed( ));
GetMousePosition(&x,&y);
while(LeftMouseKeyPressed( ));
HideMouseCursor( );
V[count].SetVertex(x,y,count);
V[count].ShowVertex( );
ShowMouseCursor( );
}
HideMouseCursor( );
setfillstyle(1,8);
bar(6,459,634,475);
setcolor(14);
settextstyle(2,0,4);
outtextxy(15,461,"Draw the Edges and enter their weights.");
ShowMouseCursor( );

int i;
int j;
int flag=0;
int weight;
for(count=0;count<edges;)
{
flag=0;

do
{
while(!LeftMouseKeyPressed( ));

for(i=0;i<vertices;i++)
{
if(V[i].Hit( ) && LeftMouseKeyPressed( ))
{
GetMousePosition(&x,&y);

HideMouseCursor( );

setcolor(11);
circle(V[i].x,V[i].y,10);

ShowMouseCursor( );

flag=1;
break;
}
}

if(flag)break;
}
while(1);

setwritemode(1);
setcolor(11);

int x_end=x;
int y_end=y;
int prev_x=x;
int prev_y=y;

while(LeftMouseKeyPressed( ))
{
GetMousePosition(&x_end,&y_end);

if(x_end!=prev_x || y_end!=prev_y)
{
HideMouseCursor( );

line(x,y,prev_x,prev_y);
line(x,y,x_end,y_end);

ShowMouseCursor( );

prev_x=x_end;
prev_y=y_end;
}
}

flag=0;
for(j=0;j<vertices;j++)
{
if(V[j].Hit( ) && j!=i)
{
HideMouseCursor( );

setcolor(11);
circle(V[j].x,V[j].y,10);

ShowMouseCursor( );

flag=1;
break;
}
}

if(flag)
{
for(int k=0;k<count;k++)
{
if((E[k].V1.label==i && E[k].V2.label==j) ||
(E[k].V2.label==i && E[k].V1.label==j))
{
flag=0;
break;
}
}
}

setwritemode(0);

HideMouseCursor( );

if(flag)
{
line(x,y,x_end,y_end);

setfillstyle(1,8);
bar(6,459,634,475);

setcolor(15);
settextstyle(2,0,4);
outtextxy(15,461,"Enter the Edge Weight = ");

weight=atoi(GetInput(145,460,3,15,8));

setfillstyle(1,8);
bar(6,459,634,475);

if(count<(edges-1))
{
setcolor(14);
settextstyle(2,0,4);
outtextxy(15,461,"Draw the Edges and enter their
weights.");
}
weight=((weight<=0)?0:weight);

E[count].SetEdge(V[i],V[j],weight);
count++;
}

setfillstyle(0,1);
bar(6,36,634,454);

ShowMouseCursor( );

for(i=0;i<vertices;i++)
V[i].ShowVertex( );

for(i=0;i<count;i++)
E[i].ShowEdge( );
}

HideMouseCursor( );

setfillstyle(1,8);
bar(6,459,634,475);

setcolor(14);
settextstyle(2,0,4);
outtextxy(15,461,"Press any Key to apply Kruskal's Algorithm...");

getch( );

setfillstyle(0,1);
bar(6,36,634,454);

setfillstyle(1,8);
bar(6,459,634,475);

setcolor(15);
settextstyle(2,0,4);
outtextxy(15,461,"Applying Kruskals's Algorithm...");

ShowMouseCursor( );

for(count=0;count<vertices;count++)
V[count].ShowVertex( );

for(i=0;i<edges;i++)
{
for(int j=0;j<(edges-1);j++)
{
if(E[j].weight>=E[(j+1)].weight)
{
Edge Temp;

Temp=E[j];
E[j]=E[(j+1)];
E[(j+1)]=Temp;
}
}
}

int e_count=0;
int cycle_flag=0;

Edge _E[MAX_EDGES];

int mst[MAX_VERTICES][MAX_VERTICES]={0};

for(i=0;i<=vertices;i++)
{
mst[i][0]=i;

for(int j=1;j<vertices;j++)
mst[i][j]=-1;
}

for(count=0;count<edges;count++)
{
cycle_flag=0;

for(i=1;i<vertices;i++)
{
if(mst[E[count].V1.label][i]==E[count].V2.label ||
mst[E[count].V2.label][i]==E[count].V1.label)
cycle_flag=1;
}

if(!cycle_flag)
{
_E[e_count]=E[count];
_E[e_count].ShowEdge( );

e_count++;

for(i=1;i<vertices;i++)
{
if(mst[E[count].V1.label][i]==E[count].V2.label)
break;

if(mst[E[count].V1.label][i]==-1)
{
mst[E[count].V1.label][i]=E[count].V2.label;

break;
}
}

for(i=1;i<vertices;i++)
{
if(mst[E[count].V2.label][i]==E[count].V1.label)
break;

if(mst[E[count].V2.label][i]==-1)
{
mst[E[count].V2.label][i]=E[count].V1.label;
break;
}
}

for(i=0;i<vertices;i++)
{
for(int j=0;j<vertices;j++)
{
for(int k=1;k<vertices;k++)
{
if(mst[j][k]!=-1)
{
for(int l=1;l<vertices;l++)
{
if(mst[mst[j][k]][l]!=-1)
{
for(int m=0;m<vertices;m++)
{
if(mst[mst[j][k]][l]==mst[j][m])
break;

if(mst[j][m]==-1)
{
mst[j][m]=mst[mst[j][k]][l];

break;
}
}
}
}
}
}
}
}

HideMouseCursor( );

settextstyle(2,0,4);

do
{
setcolor(14);
outtextxy(530,461,"Press any Key...");

delay(250);

setcolor(8);
outtextxy(530,461,"Press any Key...");

delay(250);
}
while(!kbhit( ));

getch( );

setfillstyle(1,8);
bar(500,459,634,475);

ShowMouseCursor( );
}
}

HideMouseCursor( );

setfillstyle(0,1);
bar(6,36,634,454);

setfillstyle(1,8);
bar(6,459,634,475);
bar(23,80,90,83);
bar(23,230,122,233);

setcolor(11);
settextstyle(2,0,7);
outtextxy(24,60,"Given:");
outtextxy(25,60,"Given:");
outtextxy(25,61,"Given:");

outtextxy(24,210,"Solution:");
outtextxy(25,210,"Solution:");
outtextxy(25,211,"Solution:");

setcolor(15);
settextstyle(2,0,4);
moveto(50,98);
outtext("V = {");

for(count=0;count<vertices;count++)
{
PrintText((getx( )+3),gety( ),(count+1));

if(count<(vertices-1))
{
moveto((getx( )+3),gety( ));
outtext(",");
}
}

moveto((getx( )+4),gety( ));


outtext("}");

moveto(50,117);
outtext("E = {");

for(count=0;count<edges;count++)
{
if(count==7 || count==14)
moveto(83,(gety( )+15));

else
moveto((getx( )+3),gety( ));

outtext("(");
PrintText((getx( )+2),gety( ),(E[count].V1.label+1));

moveto((getx( )+2),gety( ));


outtext(",");

PrintText((getx( )+2),gety( ),(E[count].V2.label+1));

moveto((getx( )+2),gety( ));


outtext(",");

PrintText((getx( )+2),gety( ),E[count].weight,14);

setcolor(15);

moveto((getx( )+2),gety( ));


outtext(")");

if(count<(edges-1))
{
moveto((getx( )+3),gety( ));
outtext(",");
}
}

moveto((getx( )+4),gety( ));


outtext("}");

moveto(50,248);
outtext("E = {");

for(count=0;count<e_count;count++)
{
if(e_count==7 || e_count==14)
moveto(83,(gety( )+15));

else
moveto((getx( )+3),gety( ));

outtext("(");

PrintText((getx( )+2),gety( ),(_E[count].V1.label+1));

moveto((getx( )+2),gety( ));


outtext(",");

PrintText((getx( )+2),gety( ),(_E[count].V2.label+1));

moveto((getx( )+2),gety( ));


outtext(",");

PrintText((getx( )+2),gety( ),_E[count].weight,14);

setcolor(15);

moveto((getx( )+2),gety( ));


outtext(")");
if(count<(e_count-1))
{
moveto((getx( )+3),gety( ));
outtext(",");
}
}

moveto((getx( )+4),gety( ));


outtext("}");

moveto(50,267);
outtext("Cost = ");

int cost=0;

for(count=0;count<e_count;count++)
{
cost+=_E[count].weight;

PrintText((getx( )+3),gety( ),_E[count].weight);

if(count<(e_count-1))
{
moveto((getx( )+3),gety( ));
outtext("+");
}
}

moveto((getx( )+5),gety( ));


outtext("=");

PrintText((getx( )+5),gety( ),cost);

setcolor(14);
settextstyle(2,0,4);
outtextxy(15,461,"Press any Key to Exit.");

getch( );
closegraph( );
return 0;
}

Source code: input.h


# include <ctype.h>
# include "Mouse.h"
const char* GetInput(const int x,const int y,int max_size,
const int text_color,const int text_bgcolor)
{
while(kbhit( ))
getch( );

char Input[10]={NULL};

int x_1=x;
int x_2=(x+(8*max_size)+15);
int y_1=y;
int y_2=(y+14);

setfillstyle(1,text_bgcolor);
bar(x_1,y_1,x_2,y_2);

int count=0;
int key_code=0;

char Key=NULL;

do
{
if(kbhit( ))
{
Key=NULL;
key_code=0;

Key=getch( );
key_code=int(Key);

if(key_code==13 && count>0)


break;

if(count<max_size && key_code!=8)


{
if(isdigit(Key) || Key=='+'
|| Key=='-' || Key=='.' || Key=='e')
{
Input[count]=Key;
count++;
}
}

else if(key_code==8 && count>0)


{
setfillstyle(1,text_bgcolor);
bar((x_1+1),(y_1+1),(x_2-1),(y_2-1));

count--;
Input[count]=NULL;
}
}
settextstyle(2,0,4);
setcolor(text_color);
moveto((x+5),(y+1));
outtext(Input);

int xx=getx( );
int yy=(gety( )+3);

while(!kbhit( ))
{
setcolor(text_color);
moveto(xx,yy);
outtext("-");
delay(250);

setcolor(text_bgcolor);
moveto(xx,yy);
outtext("-");

delay(200);
}
}
while(1);
return Input;
}
Source code: mouse.h
# include <graphics.h>
# include <fstream.h>
# include <dos.h>

const int InitMouse( );

void ShowMouseCursor( );
void HideMouseCursor( );

void SetMousePosition(int x,int y);


void GetMousePosition(int *x,int *y);

const int MouseHit(int x_min,int y_min,int x_max,int y_max);


const int MouseMove( );

void SetMouseHorizontalRange(int x_min,int x_max);


void SetMouseVerticalRange(int y_min,int y_max);
void SetMouseRange(int x_min,int y_min,int x_max,int y_max);

const int MouseKeyPressed( );


const int LeftMouseKeyPressed( );
const int RightMouseKeyPressed( );
const int MiddleMouseKeyPressed( );

void SetMouseCursor(const unsigned int cursor[32],


int hotspot_x,int hotspot_y);
void SetDefaultMouseCursor( );

const int LoadMouseCursor(const char* CursorFile);

const int DisableMouse( );


const int EnableMouse( );

void SetMouseSpeed(int=0);

static int cursor_visible = 0 ;


static int mouse_buttons = 0 ;
static int mouse_exists = 0 ;
static int mouse_enable = 1 ;
const int InitMouse( )
{
REGS InReg;
REGS OutReg;

InReg.x.ax=0x0000;

int86(0x33,&InReg,&OutReg);

if(OutReg.x.ax==0x0000 && OutReg.x.bx==0xFFFF)


return 0;

mouse_exists=1;
mouse_buttons=OutReg.x.bx;

return 1;
}

void ShowMouseCursor( )
{
if(cursor_visible || !mouse_exists)
return;

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0001;

int86(0x33,&InReg,&OutReg);

cursor_visible=1;
}

void HideMouseCursor( )
{
if(!cursor_visible || !mouse_exists)
return;

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0002;

int86(0x33,&InReg,&OutReg);

cursor_visible=0;
}

void SetMousePosition(int x,int y)


{
if(!mouse_exists || !cursor_visible)
return;

x=((x<0 || x>getmaxx( ))?0:x);


y=((y<0 || y>getmaxy( ))?0:y);

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0004;
InReg.x.cx=x;
InReg.x.dx=y;

int86(0x33,&InReg,&OutReg);
}

void GetMousePosition(int *x,int *y)


{
*x=0;
*y=0;

if(!mouse_exists || !cursor_visible)
return;

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0003;

int86(0x33,&InReg,&OutReg);

*x=OutReg.x.cx;
*y=OutReg.x.dx;
}

const int MouseHit(int x_min,int y_min,int x_max,int y_max)


{
if(!mouse_exists || !cursor_visible)
return 0;

x_min=((x_min<0 || x_min>getmaxx( ))?0:x_min);


x_max=((x_max<0 || x_max>getmaxx( ))?0:x_max);

y_min=((y_min<0 || y_min>getmaxy( ))?0:y_min);


y_max=((y_max<0 || y_max>getmaxy( ))?0:y_max);

int x;
int y;

GetMousePosition(&x,&y);

if(x>=x_min && x<=x_max && y>=y_min && y<=y_max)


return 1;

return 0;
}

const int MouseMove( )


{
if(!mouse_exists || !cursor_visible)
return 0;

REGS InReg;
REGS OutReg;
InReg.x.ax=0x000B;

int86(0x33,&InReg,&OutReg);

if(OutReg.x.cx!=0x0000 || OutReg.x.dx!=0x0000)
return 1;

return 0;
}

void SetMouseHorizontalRange(int x_min,int x_max)


{
if(!mouse_exists || !cursor_visible)
return;

x_min=((x_min<0 || x_min>getmaxx( ))?0:x_min);


x_max=((x_max<0 || x_max>getmaxx( ))?0:x_max);

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0007;
InReg.x.cx=x_min;
InReg.x.dx=x_max;

int86(0x33,&InReg,&OutReg);
}

void SetMouseVerticalRange(int y_min,int y_max)


{
if(!mouse_exists || !cursor_visible)
return;

y_min=((y_min<0 || y_min>getmaxy( ))?0:y_min);


y_max=((y_max<0 || y_max>getmaxy( ))?0:y_max);

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0008;
InReg.x.cx=y_min;
InReg.x.dx=y_max;

int86(0x33,&InReg,&OutReg);
}

void SetMouseRange(int x_min,int y_min,int x_max,int y_max)


{
if(!mouse_exists || !cursor_visible)
return;

SetMouseVerticalRange(y_min,y_max);
SetMouseHorizontalRange(x_min,x_max);
}

const int MouseKeyPressed( )


{
if(!mouse_exists || !cursor_visible)
return 0;

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0003;

int86(0x33,&InReg,&OutReg);

if(OutReg.x.bx==0x0001 || OutReg.x.bx==0x0002 ||
(OutReg.x.bx==0x0004 && mouse_buttons==3))
return 1;

return 0;
}

const int LeftMouseKeyPressed( )


{
if(!mouse_exists || !cursor_visible)
return 0;

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0003;

int86(0x33,&InReg,&OutReg);

return ((OutReg.x.bx==0x0001)?1:0);
}

const int RightMouseKeyPressed( )


{
if(!mouse_exists || !cursor_visible)
return 0;

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0003;

int86(0x33,&InReg,&OutReg);

return ((OutReg.x.bx==0x0002)?1:0);
}

const int MiddleMouseKeyPressed( )


{
if(!mouse_exists || !cursor_visible || mouse_buttons!=3)
return 0;

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0003;
int86(0x33,&InReg,&OutReg);

return ((OutReg.x.bx==0x0004)?1:0);
}

void SetMouseCursor(const unsigned int cursor[32],


int hotspot_x,int hotspot_y)
{
if(!mouse_exists || !cursor_visible)
return;

hotspot_x=((hotspot_x<0 || hotspot_x>15)?0:hotspot_x);
hotspot_y=((hotspot_y<0 || hotspot_y>15)?0:hotspot_y);

HideMouseCursor( );

REGS InReg;
REGS OutReg;

SREGS SegReg;

InReg.x.ax=0x0009;
InReg.x.bx=hotspot_x;
InReg.x.cx=hotspot_y;
InReg.x.dx=(unsigned)cursor;

segread(&SegReg);

SegReg.es=SegReg.ds;

int86x(0x33,&InReg,&OutReg,&SegReg);

ShowMouseCursor( );
}

void SetDefaultMouseCursor( )
{
if(!mouse_exists || !cursor_visible)
return;

const unsigned int cursor[32]={


/****----- AND Mask -----****/

0x3FFF, /* 0011111111111111 */
0x1FFF, /* 0001111111111111 */
0x0FFF, /* 0000111111111111 */
0x07FF, /* 0000011111111111 */
0x03FF, /* 0000001111111111 */
0x01FF, /* 0000000111111111 */
0x00FF, /* 0000000011111111 */
0x007F, /* 0000000001111111 */
0x003F, /* 0000000000111111 */
0x001F, /* 0000000000011111 */
0x001F, /* 0000000000011111 */
0x11FF, /* 0001000111111111 */
0x30FF, /* 0011000011111111 */
0xF8FF, /* 1111100011111111 */
0xF87F, /* 1111100001111111 */
0xFCFF, /* 1111110011111111 */

/****----- XOR Mask -----****/

0x0000, /* 0000000000000000 */
0x4000, /* 0100000000000000 */
0x6000, /* 0110000000000000 */
0x7000, /* 0111000000000000 */
0x7800, /* 0111100000000000 */
0x7C00, /* 0111110000000000 */
0x7E00, /* 0111111000000000 */
0x7F00, /* 0111111100000000 */
0x7F80, /* 0111111110000000 */
0x7FC0, /* 0111111111000000 */
0x6C00, /* 0110110000000000 */
0x4400, /* 0100010000000000 */
0x0600, /* 0000011000000000 */
0x0200, /* 0000001000000000 */
0x0300, /* 0000001100000000 */
0x0000 /* 0000000000000000 */
};

SetMouseCursor(cursor,0,0);
}

const int LoadMouseCursor(const char* CursorFile)


{
if(!mouse_exists || !cursor_visible)
return 1;

unsigned int cursor[32]={0};

int hotspot_x=0;
int hotspot_y=0;

char Signature[3]={NULL};

fstream File(CursorFile,ios::in|ios::nocreate);

if(!File)
return 2;

for(int count=0;count<32;count++)
File.read((char*)&cursor[count],sizeof(cursor[count]));

File.read((char*)&hotspot_x,sizeof(hotspot_x));
File.read((char*)&hotspot_y,sizeof(hotspot_y));
File.read((char*)&Signature,sizeof(Signature));
File.close( );

if(Signature[0]!='D' || Signature[1]!='C' || Signature[2]!='R')


return 3;

SetMouseCursor(cursor,hotspot_x,hotspot_y);
return 0;
}

const int DisableMouse( )


{
if(!mouse_exists || !mouse_enable)
return 0;

REGS InReg;
REGS OutReg;

InReg.x.ax=0x001F;

int86(0x33,&InReg,&OutReg);

if(OutReg.x.ax==0x001F)
{
mouse_enable=0;

return 1;
}

return 0;
}

const int EnableMouse( )


{
if(!mouse_exists || mouse_enable)
return 0;

REGS InReg;
REGS OutReg;

InReg.x.ax=0x0020;

int86(0x33,&InReg,&OutReg);

if(OutReg.x.ax==0x0020)
{
mouse_enable=1;

return 1;
}

return 0;
}

void SetMouseSpeed(int speed)


{
if(!mouse_exists || !cursor_visible)
return;

speed=((speed==0)?64:128);

REGS InReg;
REGS OutReg;
InReg.x.ax=0x0013;
InReg.x.dx=speed;

int86(0x33,&InReg,&OutReg);
}

References

• Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein.


Introduction to Algorithms, Second Edition. MIT Press and McGraw-Hill, 2001.
ISBN 0-262-03293-7. Section 23.2: The algorithms of Kruskal and Prim, pp.567–
574.
• Michael T. Goodrich and Roberto Tamassia. Data Structures and Algorithms in
Java, Fourth Edition. John Wiley & Sons, Inc., 2006. ISBN 0-471-73884-0.
Section 13.7.1: Kruskal's Algorithm, pp.632.

You might also like