<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Population</title>
</head>

<body>



<p align="center"><span lang="en-ca"><font size="6" color="#FF0000"><b>Shortest 
distance</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca">First</span> Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is <span lang="en-ca">first edition of fifth</span> assignment of <span lang="en-ca">comp352. </span></b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
  <pre><b><span lang="en-ca"><font size="3">How to find out distance between two vertices in a simple graph without weight?</font></span></b></pre>
</div>
<div align="left">
  <pre><font size="3"><b>Here is the <a href="GRAPH1.txt">graph input file</a>.</b></font></pre>
</div>
<div align="left">
  <font FACE="CenturySchoolbook-BoldItalic" SIZE="3"><i><b></b></i></font>
</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca"><a name="explain"></a>C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <b><span lang="en-ca">1. Using BFS. </span></b></div>
<div align="left">
  <b><span lang="en-ca">2. Using my own Matrix class as an input tool because I 
  am too lazy to write again the same routine.</span></b></div>
<div align="left">
  <b><span lang="en-ca">3. Re-write &quot;createGraph&quot; from Mr. shaffer's code 
  because I want to steal his idea.(:</span></b></div>
<div align="left">
  <b><span lang="en-ca">4. Abusively using &quot;mark&quot; as recording the distance from 
  &quot;starting&quot; vertices because I want to confuse the marker. (:</span></b></div>
<div align="left">
  <b><span lang="en-ca">5. I feel regret that I didn't use my own version of &quot;BFS&quot; 
  to finish the program because I forgot to do it.</span></b></div>
<div align="left">
  <b><span lang="en-ca">6. I kept thinking about using &quot;Kruskal&quot; or &quot;Prim&quot; 
  algorithm to make this program even capable to search distance within a 
  &quot;weighted&quot; graph. </span></b></div>
<div align="left">
  <b><span lang="en-ca">7. I should change the code a little bit to enable to 
  output the path. This requires that I modify the graph </span></b></div>
<div align="left">
  <b><span lang="en-ca">class to add one more field to represent the parent of 
  current vertex so that when finding the &quot;end&quot; vertex&quot; we can &quot;backtrack&quot; the 
  path by this information. I have done this in &quot;Kruskal&quot; algorithms because it 
  is said by the instructor of comp239 that &quot;the algorithm will give you the 
  shortest length between two vertex, the shortest path is only a side effect it 
  may give you provided you do the bookkeeping job yourself.&quot; I do miss the 
  teacher even though he is only a part-time instructor and he usually made many 
  mistakes. He is a purely mathematisian. </span></b></div>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre><b><span lang="en-ca"><font size="3">1. output shortest path.</font></span></b></pre>
</div>
<div align="left">
  <pre><b><span lang="en-ca"><font size="3">2. capable for weighted graph.</font></span></b></pre>
</div>
<div align="left">
  <pre><b><span lang="en-ca"><font size="3">3. Using Kruskal or Prim algorithms.</font></span></b></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><b><span lang="en-ca"><font size="3" color="#FF0000">//this is main program: shortest.cpp</font></span></b></pre>
</div>
<pre>/*/////////////////////////////////////////////////////////////////////////////
Author: Qingzhe Huang
Date: Nov. 26, 2003
Purpose: Use graph to search shortest distance between two vertices.
features:
	1. I changed meaning of &quot;Mark&quot; to be level or distance from starting vertex.
	2. I use my own &quot;Matrix&quot; class for input tools which requires the input of graph
	to be a adjacency matrix.
	3. After reading graph into my matrix, I iterate matrix to create graph.
	4. The BFS algorithm is straight forward as I simply check if the &quot;other&quot;
	vertex is &quot;dequeued&quot; or not. If yes, that means we find out the distance of them.
	And its mark which is the distance will be returned.
	5. All default distance is -1. So, suppose we didn't find the searching vertex, we simply
	return -1.
*/////////////////////////////////////////////////////////////////////////////


#include &lt;iostream&gt;
#include &quot;Matrix.h&quot;
#include &quot;Grlist.h&quot;
#include &quot;Graph.h&quot;
#include &quot;Grmat.h&quot;
#include &quot;AQueue.h&quot;


using namespace std;


Graph* createGraph(const char* fileName, bool edgeList=true);

void Gprint(Graph* G);

int BFS(Graph* pG, int start, int end);

int main()
{
	Graph* pG;
	pG = createGraph(&quot;c:\\graph1.txt&quot;);
	Gprint(pG);
	cout&lt;&lt;&quot;the distance between :&quot;&lt;&lt;BFS(pG, 0, 4)&lt;&lt;endl;

	return 0;
}

int BFS(Graph* pG, int start, int end)
{
	int v, w;
	int level=0;
	//set all vertex as infinite
	for (int i=0; i&lt;pG-&gt;n(); i++)
	{
		pG-&gt;setMark(i, -1);
	}
	AQueue&lt;int&gt; Q;
	Q.enqueue(start);
	//the distance of start to start is 0
	pG-&gt;setMark(start, level);
	
	while (Q.length()!=0)
	{
		Q.dequeue(v);
		if (v==end)//found out the vertex
		{
			return pG-&gt;getMark(v);//the level
		}
		level = pG-&gt;getMark(v)+1; //for all his son, the level is one more
		for (w=pG-&gt;first(v); w&lt;pG-&gt;n(); w=pG-&gt;next(v, w))
		{
			if (pG-&gt;getMark(w)==-1)
			{
				pG-&gt;setMark(w, level);
				Q.enqueue(w);
			}
		}
	}
	return -1;
}







Graph* createGraph(const char* fileName, bool edgeList)
{
	Matrix M;
	Graph* pG;
	M.readFromFile(fileName);
	M.display();
	cout&lt;&lt;endl;
	if (edgeList)
	{
		pG = new Graphl(M.col());
	}
	else
	{
		pG = new Graphm(M.col());
	}
	for (int r=0; r&lt;M.row(); r++)
	{
		for (int c=0; c&lt;M.col(); c++)
		{
			if (edgeList)
			{
				if (M.items(r, c)!=0)
				{
					pG-&gt;setEdge(r, c, M.items(r, c));
				}
			}
			else
			{
				pG-&gt;setEdge(r, c, M.items(r, c));
			}

		}
	}
	return pG;
}

void Gprint(Graph* G)
{
	int i, j;

	cout &lt;&lt; &quot;Number of vertices is &quot; &lt;&lt; G-&gt;n() &lt;&lt; &quot;\n&quot;;
	cout &lt;&lt; &quot;Number of edges is &quot; &lt;&lt; G-&gt;e() &lt;&lt; &quot;\n&quot;;

	cout &lt;&lt; &quot;Matrix is:\n&quot;;
	for (i=0; i&lt;G-&gt;n(); i++) 
	{
		for(j=0; j&lt;G-&gt;n(); j++)
		{
			cout &lt;&lt; G-&gt;weight(i, j) &lt;&lt; &quot; &quot;;
		}
		cout &lt;&lt; &quot;\n&quot;;
	}
}

</pre>
<pre><b><span lang="en-ca"><font size="3" color="#FF0000">//This is the matrix.h</font></span></b></pre>
<pre>#ifndef MATRIX_H
#define MATRIX_H

const int MaxRow = 10;
const int MaxCol = 10;
const double LIMIT = 0.01;


class Matrix
{
private:
	int rowNum;
	int colNum;
	double lst[MaxRow][MaxCol];
protected:
	void mul(int dest, double scalor);
	void mul(int source, int dest, double scalor);
public:
	Matrix();
	Matrix&amp; transform(int index1, int index2);
	int row() const {return rowNum;}
	int col() const {return colNum;}
	void setRow(const int newRow) { rowNum = newRow;}
	void setCol(const int newCol) { colNum = newCol;}
	void display(bool displayNumber= false);
	double&amp; items(int r, int c);
	void initialize();
	void readFromFile(const char* fileName);
	void assign(const Matrix&amp; other);
	Matrix&amp; operator = (Matrix&amp; other);
	Matrix&amp; transposition();	
	bool operator==(Matrix&amp; other);
	bool operator!=(Matrix&amp; other);
};

class MathMatrix: public Matrix
{
public:
	void echelon(int r, int c, bool reduced=true);
	//Linear Homogeneous Recurrsive Relation with Constant Coefficients
	void LHRRCC(double* roots, double* initials, int degree);
	Matrix&amp; operator+(Matrix other);
	Matrix&amp; operator *(double i);
	Matrix&amp; operator *(Matrix otherMatrix);  
};

class LogicMatrix: public Matrix
{
protected:
	
public:
	Matrix&amp; operator &amp;&amp;(Matrix otherMatrix);
	Matrix&amp; operator ||(Matrix otherMatrix);
	Matrix&amp; power(int exponent);
	bool reflexive();
	bool symmetric();
	bool antiSymmetric();
	bool transitive();
	bool equivalent();
	bool partialOrder();
	Matrix&amp; transitiveClosure();
	Matrix&amp; reflexiveClosure();
	Matrix&amp; symmetricClosure();
	Matrix&amp; warshall();
	bool isomorphic(LogicMatrix&amp; other);
	int calcDegree(int* array);
};

#endif</pre>
<pre>

<b><font color="#FF0000" size="3"><span lang="en-ca">//this is matrix.cpp for my matrix class used for inputting. (It will read in an matrix and</span></font></b></pre>
<pre><span lang="en-ca"><font size="3" color="#FF0000"><b>//represent that matrix. Haha...)</b></font></span></pre>
<pre>　</pre>
<pre>#include &lt;iostream&gt;
#include &lt;cmath&gt;
#include &lt;fstream&gt;
#include &quot;Matrix.h&quot;

using namespace std;

Matrix&amp; LogicMatrix::warshall()
{
	int n = row(); //n is dimention of matrix
	for (int k=0; k&lt;n; k++)
	{
		for (int r=0;r&lt;n; r++)
		{
			for (int c=0; c&lt;n; c++)
			{
				items(r,c) = items(r,c)|| items(r,k) &amp;&amp; items(k,c);
			}
		}
	}
	return *this;
}



Matrix&amp; LogicMatrix::symmetricClosure()
{
	for (int r=0; r&lt; row(); r++)
	{
		for (int c=0; c&lt; col(); c++)
		{
			if (items(r,c)==1)
			{
				items(c, r) = 1;
			}
		}
	}
	return *this;
}

Matrix&amp; LogicMatrix::reflexiveClosure()
{
	for (int i=0; i&lt;row(); i++)
	{
		items(i, i) = 1;
	}
	return *this;
}


bool LogicMatrix::partialOrder()
{
	return reflexive()&amp;&amp;antiSymmetric()&amp;&amp;transitive();
}


bool LogicMatrix::equivalent()
{
	return reflexive()&amp;&amp;symmetric()&amp;&amp;transitive();
}


Matrix&amp; LogicMatrix::transitiveClosure()
{
	int dim = col();
	LogicMatrix N;
	N = *this;
	for (int i = 1; i&lt;=dim; i++)
	{
		(Matrix)N = (Matrix)(N ||power(i));
	}
	*this = N;
	return *this;
}


Matrix&amp; LogicMatrix::operator ||(Matrix otherMatrix)
{
	int dim = col();
	for (int r = 0; r&lt; dim; r++)
	{
		for (int c=0; c&lt; dim; c++)
		{
			items(r,c) = (int)items(r,c) ||(int)otherMatrix.items(r, c);
		}
	}
	return *this;
}


bool LogicMatrix::reflexive()
{
	bool result = true;
	for (int i =0; i&lt;col(); i++)
	{
		result = result&amp;&amp;items(i, i);
	}
	return result;
}

bool LogicMatrix::symmetric()
{
	int dim = col();  //since the function will be called nxn times, better use variable.
	for (int r = 0; r&lt; dim; r++)
	{
		for (int c = r; c&lt; dim; c++)
		{			
			if ((int)items(r,c)^(int)items(c,r))//exclusive or
			{
				return false;
			}
		}
	}
	return true;
}

bool LogicMatrix::antiSymmetric()
{
	int dim = col();
	for (int r =0; r&lt; dim; r++)
	{
		for (int c = r; c&lt; dim; c++)
		{
			if (items(r,c)&amp;&amp;items(c,r))
			{
				if (r != c)
				{
					return false;
				}
			}
		}
	}
	return true;
}

int LogicMatrix::calcDegree(int *array)
{
	int degree=row();
	int index=0;
	for (int r=0; r&lt;row();r++)
	{
		for (int c=0; c&lt;col();c++)
		{
			array[r] += items(r, c);
		}
		if (array[r]&lt;degree)
		{
			degree = array[r]; //to find the smallest degree;
			index = r;
		}
	}
	return index;//the index that have smallest degree
}

bool LogicMatrix::isomorphic(LogicMatrix&amp; other)
{
	int ownIndex=0;
	int otherIndex=0;
	if (row()!=col()||row()!=other.row()||other.row()!=other.col())
	{
		return false;
	}
	int degree[MaxRow]={0};
	int otherDegree[MaxRow] = {0};
	ownIndex = this-&gt;calcDegree(degree);
	otherIndex = other.calcDegree(otherDegree);
	while (degree[ownIndex] == otherDegree[otherIndex])
	{

		return false;
	}



	return true;
}

bool LogicMatrix::transitive()
{
	int dim = col();
	for (int r =0; r&lt; dim; r++)
	{
		for (int c=0; c&lt; dim; c++)
		{
			if (items(r,c))//if find an entry which is 1's
			{
				for (int i =0; i&lt; dim; i++) // try to find in c'th row 
				{
					if (items(c, i))
					{
						if (!items(r, i))
						{
							return false;
						}
					}
				}
			}
		}
	}
	return true;
}

Matrix&amp; LogicMatrix::operator &amp;&amp;(Matrix otherMatrix)
{
	bool dummy=false;
	int dim = col();  //as this function is used so many times, better use variable, 
	for (int r =0; r&lt;dim; r++)
	{
		for (int c =0; c&lt;dim; c++)
		{
			for (int i=0; i&lt;dim; i++)
			{
				dummy = dummy||(items(r,i)&amp;&amp;otherMatrix.items(i, c));
			}
			items(r, c) = dummy;
			dummy = false;
		}
	}
	return *this;
}

Matrix&amp; LogicMatrix::power(int exponent)
{
	Matrix N;
	N = *this; //I have to copy a temp Matrix to keep original one
	for (int i=1; i&lt;exponent; i++)
	{
		this-&gt;operator &amp;&amp;(N);
	}
	return (*this);
}

Matrix&amp; Matrix::transposition()
{
	double hold;
	int temp;
	for (int r =0; r&lt; rowNum; r++)
	{
		for (int c=0; c&lt; r; c++)
		{
			hold = lst[r][c];
			lst[r][c] = lst[c][r];
			lst[c][r] = hold;
		}
	}
	temp = rowNum;
	rowNum = colNum;
	colNum = temp;
	return (*this);
}


void MathMatrix::LHRRCC(double *roots, double* initials, int degree)
{
	for (int r=0; r&lt;degree; r++)
	{
		for (int c=0;c&lt;degree; c++)
		{
			if (r==0)
			{
				items(r,c) = 1;
			}
			else
			{
				items(r,c) = items(r-1,c)*roots[c];
			}
		}
		items(r,c) = initials[r];
	}
	setRow(degree);
	setCol(degree+1);
}

Matrix&amp; MathMatrix::operator +(Matrix other)
{
	if (row()!= other.row() || col()!= other.col())
	{
		cout&lt;&lt;&quot;\nTwo matrix has different row or col number!\n&quot;;
		return (*this);
	}
	else
	{
		for (int r=0; r&lt; row(); r++)
		{
			for (int c=0; c&lt; col(); c++)
			{
				items(r, c) +=other.items(r, c);
			}
		}
		return (*this);
	}
}

Matrix&amp; MathMatrix::operator *(Matrix other)
{
	double total =0;
	Matrix temp;
	temp.setRow(row());
	temp.setCol(other.col());

	if (col()!=other.row())
	{
		cout&lt;&lt;&quot;\nrow &amp; col are not same!\n&quot;;
	
	}
	else
	{
		for (int r =0; r&lt; row(); r++)
		{
			for (int c=0; c&lt;other.col(); c++)
			{
				total =0;
				for (int i=0; i&lt;col(); i++)
				{
					total += items(r,i) * other.items(i, c);
				}
				temp.items(r, c) = total;
			}
		}
		this-&gt;assign(temp);	
	}
	return (*this);
}
	
bool Matrix::operator==(Matrix&amp; other)
{
	if (row()!=other.row()||col()!=other.col())
	{
		return false;
	}
	for (int r=0; r&lt;row(); r++)
	{
		for (int c=0; c&lt;col(); c++)
		{
			if (items(r,c)!=other.items(r,c))
			{
				return false;
			}
		}
	}
	return true;
}

bool Matrix::operator !=(Matrix&amp; other)
{
	return !(this-&gt;operator ==(other));
}
			
Matrix&amp; Matrix::operator =(Matrix&amp; other)
{
	setRow(other.row());
	setCol(other.col());
	for (int r=0; r&lt; other.row(); r++)
	{
		for (int c=0; c&lt; other.col(); c++)
		{
			lst[r][c] = other.items(r, c);
		}
	}
	
	return (*this);
}

void Matrix::assign(const Matrix&amp; other)
{
	this-&gt;operator =((Matrix&amp;)other);
}


void Matrix::mul(int dest, double scalor)
{
	for (int c=0; c&lt; colNum; c++)
	{
		lst[dest][c] *= scalor;
	}
}

Matrix&amp; MathMatrix::operator *(double i)
{
	for (int r=0; r&lt;row(); r++)
	{
		for (int c=0; c&lt;col(); c++)
		{
			items(r, c) *= i;
		}
	}
	return (*this);
}

void MathMatrix::echelon(int r, int c, bool reduced)
{
	if (r&lt;row()&amp;&amp;c&lt;col()&amp;&amp;c&lt;row())
	{
		if (items(r, c) !=0)
		{
			mul(r, 1/items(r,c));   //make it 1 for this row
			for (int i=(!reduced?r+1:0); i&lt; row(); i++)
			{
				if (i!=r)
				{
					mul(r, i, -items(i,c));
				}
			}	
			echelon(r+1, c+1, reduced);
		}
		else
		{
			echelon(r+1, c, reduced);
		}
	}
	else
	{
		if (c&lt;row()&amp;&amp;c&lt;col())
		{
			echelon(0, c, reduced);
		}
	}
}

void Matrix::mul(int source, int dest, double scalor)
{
	for (int c=0; c&lt; colNum; c++)
	{
		lst[dest][c] += lst[source][c]*scalor;
	}
}


double&amp; Matrix::items(int r, int c)
{
	return lst[r][c];
}

void Matrix::readFromFile(const char* fileName)
{
	int r=0, c=0;
	char ch;
	ifstream f;
	f.open(fileName);
	while (!f.eof())
	{
		ch = f.peek();
		
		if (ch!=10)  //return char
		{
			
			f&gt;&gt;lst[r][c];
			c++;
			if (c&gt;colNum)
				colNum = c;
		}
		else
		{
			f.ignore();
			r++;
			setCol(c);
			c =0;
		}
	}
	if (r!=0)
	{
		setRow(r+1);
	}
}


void Matrix::initialize()
{
	for (int r=0; r &lt; rowNum; r++)
	{
		for (int c=0; c&lt; colNum; c++)
		{
			lst[r][c] = r*2+c;
		}
	}	
}

Matrix&amp; Matrix::transform(int index1, int index2)
{
	double hold;
	if (index1&lt;rowNum&amp;&amp;index2&lt;rowNum)
	{
		for (int i=0; i&lt;colNum; i++)
		{
			hold = lst[index1][i];
			lst[index1][i] = lst[index2][i];
			lst[index2][i] = hold;
		}
		for (i=0; i&lt; rowNum; i++)
		{
			hold = lst[i][index1];
			lst[i][index1] = lst[i][index2];
			lst[i][index2] = hold;
		}
	}
	return *this;
}




void Matrix::display(bool displayNumber)
{
//	int temp;
	long preFlag;
	int number=0;
	preFlag = cout.flags();
//	temp = cout.precision(4);
//	cout.setf(ios::fixed);
	
	cout&lt;&lt;&quot;\nrow\\col&quot;;
	for (int c=0; c&lt; colNum; c++)
	{
		cout&lt;&lt;&quot;  &quot;&lt;&lt;c;
	}
	cout&lt;&lt;&quot;\n\n&quot;;
	for (int r = 0; r&lt; rowNum; r++)
	{
		cout&lt;&lt;r&lt;&lt;&quot;\t &quot;;
		number = 0;
		for (c = 0; c&lt; colNum; c++)
		{
			cout&lt;&lt;(fabs(lst[r][c])&lt;LIMIT?0:lst[r][c])&lt;&lt;&quot;  &quot;;
			if (fabs(lst[r][c])&gt;=LIMIT)
			{
				number++;
			}
		}
		if (displayNumber)
		{
			cout&lt;&lt;number;
		}

		cout&lt;&lt;endl;
	}
//	cout.precision(temp);
	cout.flags(preFlag);
}

Matrix::Matrix()
{
	rowNum = 5;
	colNum = 5;
	initialize();
}
</pre>
<pre>　</pre>
<pre><b><span lang="en-ca"><font size="3" color="#FF0000">//this is AQueue.h</font></span></b></pre>
<pre>#ifndef AQUEUE_H
#define AQUEUE_H
// This is the file to include in your code if you want access to the
// complete AQueue template class

// First, get the declaration for the base stack class
#include &quot;queue.h&quot;

// Array-based queue implementation
template &lt;class Elem&gt; class AQueue: public Queue&lt;Elem&gt; {
private:
  int size;                  // Maximum size of queue
  int front;                 // Index of front element
  int rear;                  // Index of rear element
  Elem *listArray;           // Array holding queue elements
public:
  AQueue(int sz =DefaultListSize) { // Constructor 
    // Make list array one position larger for empty slot
    size = sz+1;
    rear = 0;  front = 1;
    listArray = new Elem[size];
  }
  ~AQueue() { delete [] listArray; } // Destructor
  void clear() { front = rear; }
  bool enqueue(const Elem&amp; it) {
    if (((rear+2) % size) == front) return false;  // Full
    rear = (rear+1) % size; // Circular increment
    listArray[rear] = it;
    return true;
  }
  bool dequeue(Elem&amp; it) {
    if (length() == 0) return false;  // Empty
    it = listArray[front];
    front = (front+1) % size; // Circular increment
    return true;
  }
  bool frontValue(Elem&amp; it) const {
    if (length() == 0) return false;  // Empty
    it = listArray[front];
    return true;
  }
  virtual int length() const
   { return ((rear+size) - front + 1) % size; }
};

#endif</pre>
<pre><b><span lang="en-ca"><font size="3" color="#FF0000">//this is base class Queue----Queue.h</font></span></b></pre>
<pre><span lang="en-ca">#ifndef QUEUE_H
#define QUEUE_H

// Abstract queue class
template &lt;class Elem&gt; class Queue {
public:
// Reinitialize the queue. The user is responsible for
// reclaiming the storage used by the stack elements.
virtual void clear() = 0;
// Place an element at the rear of the queue. Return
// true if successful, false if not (if queue is full).
virtual bool enqueue(const Elem&amp;) = 0;
// Remove the element at the front of the queue. Return
// true if succesful, false if queue is empty.
// The element removed is returned in the first parameter.
virtual bool dequeue(Elem&amp;) = 0; // Remove Elem from front
// Return in first parameter a copy of the front element.
// Return true if succesful, false if queue is empty.
virtual bool frontValue(Elem&amp;) const = 0;
// Return the number of elements in the queue.
virtual int length() const = 0;
};

#endif</span></pre>
<pre><b><font color="#FF0000" size="3"><span lang="en-ca">//this is link.h</span></font></b></pre>
<pre>#ifndef LINK_H
#define LINK_H

// Singly-linked list node
template &lt;class Elem&gt; class Link {
public:
  Elem element;      // Value for this node
  Link *next;        // Pointer to next node in list
  Link(const Elem&amp; elemval, Link* nextval =NULL)
    { element = elemval;  next = nextval; }
  Link(Link* nextval =NULL) { next = nextval; }
};

#endif</pre>
<pre><b><span lang="en-ca"><font size="3" color="#FF0000">//this is list.h</font></span></b></pre>
<pre>#ifndef LIST_H
#define LIST_H

// List abstract class
template &lt;class Elem&gt; class List {
public:
  // Reinitialize the list.  The client is responsible for
  // reclaiming the storage used by the list elements.
  virtual void clear() = 0;
  // Insert an element at the front of the right partition.
  // Return true if successful, false if the list is full.
  virtual bool insert(const Elem&amp;) = 0;
  // Append an element at the end of the right partition.
  // Return true if successful, false if the list is full.
  virtual bool append(const Elem&amp;) = 0;
  // Remove the first element of right partition. Return
  // true if successful, false if right partition is empty.
  // The element removed is returned in the parameter.
  virtual bool remove(Elem&amp;) = 0;
  // Place fence at list start, making left partition empty
  virtual void setStart() = 0;
  // Place fence at list end, making right partition empty
  virtual void setEnd() = 0;
  // Move fence one step left; no change if already at start
  virtual void prev() = 0;
  // Move fence one step right; no change if already at end
  virtual void next() = 0;
  // Return length of left partition
  virtual int leftLength() const = 0;
  // Return length of right partition
  virtual int rightLength() const = 0;
  // If pos or more elements are in the list, set the size
  // of left partition to pos and return true.  Otherwise,
  // do nothing and return false.
  virtual bool setPos(int pos) = 0;
  // Return in first parameter the first element  of the
  // right partition.  Return true if successful, false
  // if the right partition is empty.
  virtual bool getValue(Elem&amp;) const = 0;
  // Print the contents of the list
  virtual void print() const = 0;
};

#endif</pre>
<pre><b><span lang="en-ca"><font size="3" color="#FF0000">//this is llist.h (the link-list)</font></span></b></pre>
<pre>#ifndef LLIST_H
#define LLIST_H

// This is the file to include in your code if you want access to the
// complete LList template class

// First, get the declaration for the base list class
#include &quot;list.h&quot;

const int DefaultListSize=50;

// Linked list implementation
template &lt;class Elem&gt; class LList: public List&lt;Elem&gt; {
private:
  Link&lt;Elem&gt;* head;       // Pointer to list header
  Link&lt;Elem&gt;* tail;       // Pointer to last Elem in list 
  Link&lt;Elem&gt;* fence;      // Last element on left side
  int leftcnt;            // Size of left partition
  int rightcnt;           // Size of right partition
  void init() {           // Intialization routine
    fence = tail = head = new Link&lt;Elem&gt;;
    leftcnt = rightcnt = 0;
  }
  void removeall() {   // Return link nodes to free store
    while(head != NULL) {
      fence = head;
      head = head-&gt;next;
      delete fence;
    }
  }
public:
  LList(int size=DefaultListSize) { init(); }
  ~LList() { removeall(); }  // Destructor
  void clear() { removeall(); init(); }
  bool insert(const Elem&amp;);
  bool append(const Elem&amp;);
  bool remove(Elem&amp;);
  void setStart()
    { fence = head; rightcnt += leftcnt; leftcnt = 0; }
  void setEnd()
    { fence = tail; leftcnt += rightcnt; rightcnt = 0; }
  void prev();
  void next() {
    if (fence != tail) // Don't move fence if right empty
      { fence = fence-&gt;next; rightcnt--; leftcnt++; }
  }
  int leftLength() const  { return leftcnt; }
  int rightLength() const { return rightcnt; }
  bool setPos(int pos);
  bool getValue(Elem&amp; it) const {
    if(rightLength() == 0) return false;
    it = fence-&gt;next-&gt;element;
    return true;
  }
  void print() const;
};

template &lt;class Elem&gt; // Insert at front of right partition
bool LList&lt;Elem&gt;::insert(const Elem&amp; item) {
  fence-&gt;next = new Link&lt;Elem&gt;(item, fence-&gt;next);  
  if (tail == fence) tail = fence-&gt;next;  // New tail
  rightcnt++;
  return true;
}

template &lt;class Elem&gt; // Append Elem to end of the list
bool LList&lt;Elem&gt;::append(const Elem&amp; item) {
  tail = tail-&gt;next = new Link&lt;Elem&gt;(item, NULL);
  rightcnt++;
  return true;
}

// Remove and return first Elem in right partition
template &lt;class Elem&gt; bool LList&lt;Elem&gt;::remove(Elem&amp; it) {
  if (fence-&gt;next == NULL) return false; // Empty right
  it = fence-&gt;next-&gt;element;       // Remember value
  Link&lt;Elem&gt;* ltemp = fence-&gt;next; // Remember link node
  fence-&gt;next = ltemp-&gt;next;       // Remove from list
  if (tail == ltemp) tail = fence; // Reset tail
  delete ltemp;                    // Reclaim space
  rightcnt--;
  return true;
}

// Move fence one step left; no change if left is empty
template &lt;class Elem&gt; void LList&lt;Elem&gt;::prev() {
  Link&lt;Elem&gt;* temp = head;
  if (fence == head) return; // No previous Elem
  while (temp-&gt;next!=fence) temp=temp-&gt;next;
  fence = temp;
  leftcnt--; rightcnt++;
}

// Set the size of left partition to pos
template &lt;class Elem&gt; bool LList&lt;Elem&gt;::setPos(int pos) {
  if ((pos &lt; 0) || (pos &gt; rightcnt+leftcnt)) return false;
  fence = head;
  for(int i=0; i&lt;pos; i++) fence = fence-&gt;next;
  return true;
}

template &lt;class Elem&gt; void LList&lt;Elem&gt;::print() const {
  Link&lt;Elem&gt;* temp = head;
  cout &lt;&lt; &quot;&lt; &quot;;
  while (temp != fence) {
    cout &lt;&lt; temp-&gt;next-&gt;element &lt;&lt; &quot; &quot;;
    temp = temp-&gt;next;
  }
  cout &lt;&lt; &quot;| &quot;;
  while (temp-&gt;next != NULL) {
    cout &lt;&lt; temp-&gt;next-&gt;element &lt;&lt; &quot; &quot;;
    temp = temp-&gt;next;
  }
  cout &lt;&lt; &quot;&gt;\n&quot;;
}


#endif</pre>
<pre>　</pre>
<pre><b><span lang="en-ca"><font size="3" color="#FF0000">//this is graph.h</font></span></b></pre>
<pre>#ifndef GRAPH_H
#define GRAPH_H

// Graph abstract class
class Graph {
public:
  // Return the number of vertices
  virtual int n() =0;
  // Return the current number of edges
  virtual int e() =0;
  // Return the index of the first neigbor of given vertex
  virtual int first(int) =0;
  // Return the index of the next neigbor of given vertex
  virtual int next(int, int) =0;
  // Store an edge defined by two vertices and weight
  virtual void setEdge(int, int, int) =0;
  // Delete edge defined by two vertices
  virtual void delEdge(int, int) =0;
  // Return weight of edge connecting two vertices
  // Return 0 if no such edge exists
  virtual int weight(int, int) =0;
  // Get mark value for a vertex
  virtual int getMark(int) =0;
  //  Set mark value for a vertex
  virtual void setMark(int, int) =0;

};

#endif</pre>
<pre><b><span lang="en-ca"><font size="3" color="#FF0000">//this is grlist.h</font></span></b></pre>
<pre>#ifndef GRLIST_H
#define GRLIST_H
#include &lt;iostream&gt;

using namespace std;

// Used by the mark array
#define UNVISITED 0
#define VISITED 1

#include &quot;link.h&quot;
#include &quot;llist.h&quot;

#include &quot;graph.h&quot;


class Edge {
public:
  int vertex, weight;
  Edge() { vertex = -1; weight = -1; }
  Edge(int v, int w) { vertex = v; weight = w; }
};

// Overload for the Edge &lt;&lt; operator
ostream&amp; operator &lt;&lt; (ostream&amp; s, Edge e)
  { return(s &lt;&lt; &quot;(&quot; &lt;&lt; e.vertex &lt;&lt; &quot;, &quot; &lt;&lt; e.weight &lt;&lt; &quot;)&quot;); }

class Graphl : public Graph { // Implement adjacency list
private:
  int numVertex, numEdge;     // Number of vertices, edges
  List&lt;Edge&gt;** vertex; // List headers
  int *mark;                  // Pointer to mark array
public:
  Graphl(int numVert) { // Make graph with numVert vertices
    int i;
    numVertex = numVert;  numEdge = 0;
    mark = new int[numVert]; // Initialize mark array
    for (i=0; i&lt;numVertex; i++) mark[i] = UNVISITED;
    // Create and initialize adjacency lists
    vertex = (List&lt;Edge&gt;**) new List&lt;Edge&gt;*[numVertex];
    for (i=0; i&lt;numVertex; i++)
      vertex[i] = new LList&lt;Edge&gt;();
  }

  ~Graphl() {       // Destructor
    delete [] mark; // Return dynamically allocated memory
    for (int i=0; i&lt;numVertex; i++) delete [] vertex[i];
    delete [] vertex;
  }

  int n() { return numVertex; } // Number of vertices
  int e() { return numEdge; }   // Number of edges

  int first(int v) { // Return first neighbor of v
    Edge it;
    vertex[v]-&gt;setStart();
    if (vertex[v]-&gt;getValue(it)) return it.vertex;
    else return numVertex;  // Return n if none
  }

  int next(int v1, int v2) { // Gete v1's neighbor after v2
    Edge it;
    vertex[v1]-&gt;getValue(it);
    if (it.vertex == v2) vertex[v1]-&gt;next();
    else { // Start from beginning of list
      vertex[v1]-&gt;setStart();
      while (vertex[v1]-&gt;getValue(it) &amp;&amp; (it.vertex &lt;= v2))
        vertex[v1]-&gt;next();
    }
    if (vertex[v1]-&gt;getValue(it)) return it.vertex;
    else return numVertex;  // Return n if none
  }

  // Set edge (v1, v2) to wgt
  void setEdge(int v1, int v2, int wgt) {
//   Assert(wgt&gt;0, &quot;Illegal weight value&quot;);
    Edge it(v2, wgt);
    Edge curr;
    vertex[v1]-&gt;getValue(curr);
    if (curr.vertex != v2) // If not already there, search
      for (vertex[v1]-&gt;setStart();
           vertex[v1]-&gt;getValue(curr); vertex[v1]-&gt;next())
        if (curr.vertex &gt;= v2) break;
    if (curr.vertex == v2)  // Clear out the current one
      vertex[v1]-&gt;remove(curr);
    else numEdge++;
    vertex[v1]-&gt;insert(it);
  }

  void delEdge(int v1, int v2) { // Delete edge (v1, v2)
    Edge curr;
    vertex[v1]-&gt;getValue(curr);
    if (curr.vertex != v2)  // If not already there, search
      for (vertex[v1]-&gt;setStart();
           vertex[v1]-&gt;getValue(curr); vertex[v1]-&gt;next())
        if (curr.vertex &gt;= v2) break;
    if (curr.vertex == v2) {  // If not, then there is none
      vertex[v1]-&gt;remove(curr);
      numEdge--;
    }
  }

  int weight(int v1, int v2) { // Return weight of (v1, v2)
    Edge curr;
    vertex[v1]-&gt;getValue(curr);
    if (curr.vertex != v2) // If not already there, search
      for (vertex[v1]-&gt;setStart();
           vertex[v1]-&gt;getValue(curr); vertex[v1]-&gt;next())
        if (curr.vertex &gt;= v2) break;
    if (curr.vertex == v2)
      return curr.weight;
    else
      return 0;  // No such edge
  }

  int getMark(int v) { return mark[v]; }
  void setMark(int v, int val) { mark[v] = val; }
};

#endif
</pre>
<pre><b><span lang="en-ca"><font size="3" color="#FF0000">//this is grmat.h</font></span></b></pre>
<pre>#ifndef GRMAT_H
#define GRMAT_H


// Used by the mark array
#define UNVISITED 0
#define VISITED 1

#include &quot;graph.h&quot;

class Graphm : public Graph { // Implement adjacency matrix
private:
  int numVertex, numEdge; // Store number of vertices, edges
  int **matrix;           // Pointer to adjacency matrix
  int *mark;              // Pointer to mark array
public:
  Graphm(int numVert) {   // Make graph w/ numVert vertices
    int i;
    numVertex = numVert;
    numEdge = 0;
    mark = new int[numVert]; // Initialize mark array
    for (i=0; i&lt;numVertex; i++)
      mark[i] = UNVISITED;
    matrix = (int**) new int*[numVertex]; // Make matrix
    for (i=0; i&lt;numVertex; i++)
      matrix[i] = new int[numVertex];
    for (i=0; i&lt; numVertex; i++) // Edges start w/ 0 weight
      for (int j=0; j&lt;numVertex; j++) matrix[i][j] = 0;
  }

  ~Graphm() {       // Destructor
    delete [] mark; // Return dynamically allocated memory
    for (int i=0; i&lt;numVertex; i++)
      delete [] matrix[i];
    delete [] matrix;
  }

  int n() { return numVertex; } // Number of vertices
  int e() { return numEdge; }   // Number of edges

  int first(int v) {            // Return v's first neighbor
    int i;
    for (i=0; i&lt;numVertex; i++)
      if (matrix[v][i] != 0) return i;
    return i;       // Return n if none
  }

  int next(int v1, int v2) { // Get v1's neighbor after v2
    int i;
    for(i=v2+1; i&lt;numVertex; i++)
      if (matrix[v1][i] != 0) return i;
    return i;
  }

  // Set edge (v1, v2) to wgt
  void setEdge(int v1, int v2, int wgt) {
//    Assert(wgt&gt;0, &quot;Illegal weight value&quot;);
    if (matrix[v1][v2] == 0) numEdge++;
    matrix[v1][v2] = wgt;
  }

  void delEdge(int v1, int v2) { // Delete edge (v1, v2)
    if (matrix[v1][v2] != 0) numEdge--;
    matrix[v1][v2] = 0;
  }

  int weight(int v1, int v2) { return matrix[v1][v2]; }
  int getMark(int v) { return mark[v]; }
  void setMark(int v, int val) { mark[v] = val; }
};

#endif
</pre>
<pre>　</pre>
<pre><font color="#FF0000"><b><a name="input"></a>Here is the graph input file. If you run into some strange problem, try to check if you put this data into txt file and </b></font></pre>
<pre><font color="#FF0000"><b>make sure that delete all invisible character after each line, especially the last line. &quot;Enter&quot; character always is the </b></font></pre>
<pre><font color="#FF0000"><b>killer. Or you can <a href="GRAPH1.txt">down load from here.</a></b></font></pre>
<pre><span lang="en-ca">0 0 1 0 1 0
0 0 1 0 0 1
1 1 0 1 0 1
0 0 1 0 0 1
1 0 0 0 0 1
0 1 1 1 1 0</span></pre>
<pre>　</pre>
<pre>　</pre>
<pre>
</pre>
<pre>　</pre>

<pre></pre>

<pre></pre>
<pre>	
</pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="WhoAmI.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>