组合数学实验——二分图匹配算法

大一时候写的代码,忽然翻了出来....

算法:组合数学中文第4版 机械工业出版社 P234

ID就先隐藏掉了

//////////////////////////////////////////////
//                                          //
//  Project Name: matching                  //
//                                          // 
//  Author: Victor Zhang                    //
//                                          //
//  ID: 21*****92                           //
//                                          //
//  Create Date: March 31. 2009             //
//                                          //
//////////////////////////////////////////////

#include <iostream>
#include <iomanip>

using namespace std;

struct Node
{
	int i;//col
	int j;//row
	int tag;//-1='*', 0=Empty, -2=Locked
	int link;//-1=Empty, 0=Locked
	bool flag;//search flag
	Node* down;
	Node* right;
};

class Graph
{
private:
	Node* head;
	int row;
	int col;
	int num;
	bool newFlagPro1;
	bool newFlagPro3;
	bool proReady;
	bool breakPoint;
	void pro1();
	void pro2();
	void pro3();
	void pro4();
	void pro5();
	void Graph_prelink();
	void Graph_initializeNodes();
	void Graph_checkBreakPoint();
	void Graph_link();
public:
	Graph();
	~Graph();
	bool Node_add(int, int);
	void Node_deleteAll();
	void Node_deleteRow(Node*);
	bool Graph_initializeFrame(int, int);
	bool Graph_readFromFile();
	void Graph_printToFile();
	void Graph_pro();
};
//////////////////////////////////////////////
//                                          //
//  Project Name: matching                  //
//                                          //
//  File Name: matching.cpp                 //
//                                          //
//  Author: Victor Zhang                    //
//                                          //
//  ID: 21*****92                           //
//                                          //
//  Create Date: March 31. 2009             //
//                                          //
//////////////////////////////////////////////

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

#include "matching.h"

Graph::Graph()
{
	this->col = 0;
	this->row = 0;
	this->num = 0;
	this->head = NULL;
	if (!(this->Graph_readFromFile()))
	{
		this->Node_deleteAll();
		this->col = 0;
		this->row = 0;
		this->num = 0;
		this->head = NULL;
	};
};

Graph::~Graph()
{
	this->Node_deleteAll();
	this->col = 0;
	this->row = 0;
	this->num = 0;
	this->head = NULL;
};

bool Graph::Node_add(int col, int row)
{
	Node* cur_c;
	Node* cur_r;
	Node* p;
	Node* p_pre;
	Node* n_Node;
	if (!head) return false;
	n_Node = new Node;
	if (!n_Node) return false;
	n_Node->down = n_Node->right = NULL;
	n_Node->link = 0;
	cur_c = cur_r = p = this->head;
	//col
	p = cur_c->right;
	while (p && p->i <= col)
	{
		cur_c = p;
		p = p->right;
	};
	if (cur_c->i < col)//Overflow
	{
		delete n_Node;
		return false;
	};
	p_pre = cur_c->down;
	p = p_pre;
	if (p_pre) p = p_pre->down;
	while (p && (p->j <= row))
	{
		p_pre = p;
		p = p->down;
	};
	if (p_pre)
	{
		if (p_pre->j == row)
		{
			delete n_Node;
			return true;
		}
		else if (p_pre->j < row)
		{
			p_pre->down = n_Node;
			n_Node->down = p;
			this->num++;
		}
		else
		{
			cur_c->down = n_Node;
			n_Node->down = p_pre;
			this->num++;
		};
	}
	else
	{
		cur_c->down = n_Node;
		this->num++;
	};
	p = cur_r->down;
	while (p && p->j <= row)
	{
		cur_r = p;
		p = p->down;
	};
	if (cur_r->j < row)//Overflow
	{
		delete n_Node;
		return false;
	};
	p_pre = cur_r->right;
	p = p_pre;
	if (p_pre) p = p_pre->right;
	while (p && (p->i <= col))
	{
		p_pre = p;
		p = p->right;
	};
	if (p_pre)
	{
		if (p_pre->i == col)
		{
			delete n_Node;
			return true;
		}
		else if (p_pre->i < col)
		{
			p_pre->right = n_Node;
			n_Node->right = p;
		}
		else
		{
			cur_r->right = n_Node;
			n_Node->right = p_pre;
		};
	}
	else
	{
		cur_r->right = n_Node;
	};
	n_Node->i = col;
	n_Node->j = row;
	n_Node->flag = true;
	n_Node->tag = -2;
	return true;
};

void Graph::Node_deleteAll()
{
	if (!head) return;
	Node* m_p;
	Node* m_down;
	m_p = head;
	m_down = head->down;
	this->Node_deleteRow(m_p);
	while (m_down)
	{
		m_p = m_down;
		m_down = m_down->down;
		this->Node_deleteRow(m_p);
	};
	this->num = 0;
};

void Graph::Node_deleteRow(Node* m_head)
{
	if (!m_head) return;
	Node* m_p;
	Node* m_right;
	m_p = m_head;
	m_right = m_head->right;
	delete m_p;
	while (m_right)
	{
		m_p = m_right;
		m_right = m_right->right;
		delete m_p;
	};
};

bool Graph::Graph_initializeFrame(int i, int j)
{
	if (i <= 0 || j <= 0) return false;
	Node* n_Node;
	n_Node = new Node;
	if (!n_Node) return false;
	this->head = n_Node;
	this->head->down = this->head->right = NULL;
	this->head->flag = true;
	this->head->tag = -2;
	this->head->link = 0;
	this->head->i = this->head->j = 0;
	int mCol, mRow;
	mCol = mRow = 0;
	Node* cur_c;
	Node* cur_r;
	cur_c = cur_r = this->head;
	for (mCol = 0; mCol < i; mCol++)
	{
		n_Node = new Node;
		if (!n_Node) return false;
		cur_c->right = n_Node;
		n_Node->down = n_Node->right = NULL;
		n_Node->flag = false;
		n_Node->tag = 0;
		n_Node->i = (mCol + 1);
		n_Node->j = 0;
		n_Node->link = -1;
		cur_c = n_Node;
	};
	for (mRow = 0; mRow < i; mRow++)
	{
		n_Node = new Node;
		if (!n_Node) return false;
		cur_r->down = n_Node;
		n_Node->down = n_Node->right = NULL;
		n_Node->flag = false;
		n_Node->tag = 0;
		n_Node->i = 0;
		n_Node->j = (mRow + 1);
		n_Node->link = -1;
		cur_r = n_Node;
	};
	this->col = i;
	this->row = j;
	return true;
};

bool Graph::Graph_readFromFile()
{
	ifstream inputFile ("Graph_data.txt", ios::in);
	if (!inputFile)
	{
		cout<<"Error in reading file :\"Graph_data.txt\"."<<endl;
		system("pause");
		return false;
	};
	try
	{
		int mCol, mRow;
		inputFile>>mCol>>mRow;
		if (!(this->Graph_initializeFrame(mCol, mRow))) return false;
		while(inputFile>>mCol>>mRow)
			if (!(this->Node_add(mCol,mRow)))
				return false;
	}
	catch(...)
	{
		cout<<"Error in reading file :\"Graph_data.txt\"."<<endl;
		system("pause");
		inputFile.close();
		return false;
	};
	inputFile.close();
	return true;
};

void Graph::Graph_printToFile()
{
	ofstream outputFile ("Graph_output.txt", ios::out);
	Node* p;
	p = this->head;
	while (p)
	{
		p = p->right;
		if (p)
		{
			if (p->link != -1)
				outputFile<<(p->i)<<"\t"<<(p->link)<<"\n";
		};
	};
};

void Graph::Graph_pro()
{
	if (!(this->head)) return;
	this->breakPoint = true;
	this->Graph_prelink();
	while (this->breakPoint)
	{
		this->proReady = false;
		this->pro1();
ProPro2:
		this->pro2();
		if (this->proReady)
			goto ProReadyP;
		this->pro3();
		this->pro4();
		if (this->proReady)
			goto ProReadyP;
		this->pro5();
		goto ProPro2;
ProReadyP:
		this->Graph_checkBreakPoint();
		this->Graph_link();
		this->Graph_initializeNodes();
	};
	this->Graph_printToFile();
};

void Graph::pro1()
{
	this->newFlagPro1 = false;
	Node* p;
	p = this->head;
	p = p->right;
	while (p)
	{
		p->flag = false;
		if (p->link == -1)
		{
			p->tag = -1;
			this->newFlagPro1 = true;
		};
		p = p->right;
	};
};

void Graph::pro2()
{
	this->proReady = !(this->newFlagPro1);
};

void Graph::pro3()
{
	this->newFlagPro3 = false;
	Node* pCol;
	Node* pRow;
	int mRow;
	mRow = 0;
	pCol = pRow = this->head;
	pRow = this->head->down;
	pCol = this->head->right;
	Node* p;
	if ((!pCol) || (!pRow)) return;
	while (pCol)
	{
		if ((pCol->tag != 0) && !(pCol->flag))
		{
			this->newFlagPro3 = true;
			pCol->flag = true;
			p = pCol->down;
			while (p)
			{
				mRow = p->j;
				while (pRow && (pRow->j != mRow))
				{
					pRow = pRow->down;
				};
				if (pRow && (pRow->link != pCol->i) && (pRow->tag == 0))
				{
					pRow->tag = pCol->i;
				};
				p = p->down;
			};
			pRow = this->head->down;
		};
		pCol = pCol->right;
	};
};

void Graph::pro4()
{
	this->proReady = !(this->newFlagPro3);
};

void Graph::pro5()
{
	this->newFlagPro1 = false;
	Node* pCol;
	Node* pRow;
	int mCol;
	mCol = 0;
	pCol = pRow = this->head;
	pRow = this->head->down;
	pCol = this->head->right;
	Node* p;
	if ((!pCol) || (!pRow)) return;
	while (pRow)
	{
		if ((pRow->tag != 0) && !(pRow->flag))
		{
			this->newFlagPro1 = true;
			pRow->flag = true;
			p = pRow->right;
			while (p)
			{
				mCol = p->i;
				while (pCol && (pCol->i != mCol))
				{
					pCol = pCol->right;
				};
				if (pCol && (pCol->link == pRow->j) && (pCol->tag == 0))
				{
					pCol->tag = pRow->j;
				};
				p = p->right;
			};
			pCol = this->head->right;
		};
		pRow = pRow->down;
	};
};

void Graph::Graph_prelink()
{
	Node* pCol;
	Node* pRow;
	int mRow;
	mRow = 0;
	pCol = pRow = this->head;
	if (!this->head) return;
	pRow = this->head->down;
	pCol = this->head->right;
	Node* p;
	if ((!pCol) || (!pRow)) return;
	while (pCol)
	{
		p = pCol->down;
		while (p)
		{
			mRow = p->j;
			while (pRow && (pRow->j != mRow))
			{
				pRow = pRow->down;
			};
			if (pRow && pRow->link == -1)
			{
				pRow->link = pCol->i;
				pCol->link = pRow->j;
				break;
			};
			p = p->down;
		};
		pCol = pCol->right;
		pRow = this->head->down;
	};
};

void Graph::Graph_initializeNodes()
{
	Node* p;
	if (!(this->head)) return;
	p = this->head->right;
	while (p)
	{
		p->flag = false;
		p->tag = 0;
		p = p->right;
	};
	p = this->head->down;
	while (p)
	{
		p->flag = false;
		p->tag = 0;
		p = p->down;
	};
};

void Graph::Graph_checkBreakPoint()
{
	this->breakPoint = false;
	Node* p;
	if (!(this->head)) return;
	p = this->head->down;
	while (p)
	{
		if ((p->link == -1) && (p->tag != 0))
		{
			this->breakPoint = true;
			return;
		};
		p = p->down;
	};
};

void Graph::Graph_link()
{
	Node* p;
	if (!(this->head)) return;
	p = this->head->down;
	while (p)
	{
		if ((p->link == -1) && (p->tag != 0)) break;
		p = p->down;
	};
	Node* pp;
	pp = NULL;
	Node* ppp;
	ppp = p;
	if (!p) return;
	while (1)
	{
		pp = this->head->right;
		while (pp && (pp->i != ppp->tag))
			pp = pp->right;
		if (!pp)
		{
			cout<<"Error....";
			exit(1);
		};
		pp->link = ppp->j;
		ppp->link = pp->i;
		if ((pp->tag == 0) || (pp->tag == -1) || (pp->tag == ppp->i) || (pp == p)) break;
		ppp = this->head->down;
		while (ppp && (ppp->j != pp->tag))
			ppp = ppp->down;
		if (!ppp)
		{
			cout<<"Error....";
			exit(2);
		};
		if ((ppp->tag == 0) || (ppp->tag == -1) || (ppp->tag == pp->i) || (ppp == p)) break;
	};
};
//////////////////////////////////////////////
//                                          //
//  Project Name: matching                  //
//                                          //
//  File Name: main.cpp                     //
//                                          //
//  Author: Victor Zhang                    //
//                                          //
//  ID: 21*****92                           //
//                                          //
//  Create Date: March 31. 2009             //
//                                          //
//////////////////////////////////////////////

#include <iostream>

using namespace std;

#include "matching.h"

void main()
{
	Graph a;
	a.Graph_pro();
};

你可能感兴趣的:(匹配,组合数学,二分图)