大一时候写的代码,忽然翻了出来....
算法:组合数学中文第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(); };