大一时候写的代码,忽然翻了出来....
算法:组合数学中文第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();
};
来源:oschina
链接:https://my.oschina.net/u/120899/blog/14597