#include <iostream>
#include <vector>
#include <fstream>
#include <cassert>
using namespace std;
template<class InfoType, class VertexType>
class OLGraph
{
struct ArcBox
{//弧结点
size_t tail_vex;//弧尾
size_t head_vex;//弧头
ArcBox *hlink;//指向弧头相同的下一条弧
ArcBox *tlink;//指向弧尾相同的下一条弧
InfoType info;//弧结点存储的信息
};
struct VexNode
{//顶点结点
VertexType data;//顶点值
ArcBox *firstin;//以该顶点为弧头的第一个弧结点
ArcBox *firstout;//以该顶点为弧尾的第一个弧结点
};
public:
OLGraph();//输入构造图
OLGraph(fstream &file);//从文件构造图
InfoType get_info(VertexType v1, VertexType v2);//获取两结点所在弧的信息
private:
size_t locate_vex(VertexType v);//确定顶点值在容器中的位置
public:
vector<VexNode> xlist;//存储顶点结点
size_t vex_num;//顶点个数
size_t arc_num;//弧个数
bool IncInfo;//弧是否有附加信息
};
template<class InfoType, class VertexType>
OLGraph<InfoType, VertexType>::OLGraph()
{
//构造有向图
cout << "input the total of vertex number and arc number, is IncInfo true? " << endl;
cin >> vex_num >> arc_num >> IncInfo;
cout << "input each vertex value: " << endl;
VexNode tmp;
for (size_t i=0; i<vex_num; ++i)
{
//输入顶点的值
cin.clear();
cin >> tmp.data;
tmp.firstin = tmp.firstout = NULL;
xlist.push_back(tmp);
}
for (size_t k=0; k<arc_num; ++k)
{//输入两顶点的弧
cout << "input two points of the arc and the arcinfo" << endl;
VertexType v1, v2;
InfoType info;
cin.clear();
if (IncInfo) cin >> v1 >> v2 >> info;
else cin >> v1 >> v2;
size_t i = locate_vex(v1);
size_t j = locate_vex(v2);
ArcBox *p = new ArcBox;
//*p = {i, j, xlist[j].firstin, xlist[i].firstout, NULL};
p->tail_vex = i;
p->head_vex = j;
p->hlink = xlist[j].firstin;
p->tlink = xlist[i].firstout;
p->info = info;
xlist[j].firstin = xlist[i].firstout = p;
}
}
template<class InfoType, class VertexType>
size_t OLGraph<InfoType, VertexType>::locate_vex(VertexType v)
{
size_t i=0;
size_t length = xlist.size();
for (; i<length; ++i)
{
if (xlist[i].data == v) return i;
}
exit(1);
}
template<class InfoType, class VertexType>
InfoType OLGraph<InfoType, VertexType>::get_info(VertexType v1, VertexType v2)
{
size_t i = locate_vex(v1);
size_t j = locate_vex(v2);
ArcBox *p = xlist[i].firstout;
while (NULL != p)
{
if (p->head_vex == j) return p->info;
else p = p->tlink;
}
exit(2);
}
template<class InfoType, class VertexType>
OLGraph<InfoType, VertexType>::OLGraph(fstream &file)
{
//从文件构造有向图
if (file.fail()) exit(3);
//cout << "input the total of vertex number and arc number, is IncInfo true? " << endl;
file >> vex_num >> arc_num >> IncInfo;
//cout << "input each vertex value: " << endl;
VexNode tmp;
for (size_t i=0; i<vex_num; ++i)
{
//输入顶点的值
//cin.clear();
file >> tmp.data;
tmp.firstin = tmp.firstout = NULL;
xlist.push_back(tmp);
}
for (size_t k=0; k<arc_num; ++k)
{//输入两顶点的弧
//cout << "input two points of the arc and the arcinfo" << endl;
VertexType v1, v2;
InfoType info;
//cin.clear();
if (IncInfo) file >> v1 >> v2 >> info;
else file >> v1 >> v2;
size_t i = locate_vex(v1);
size_t j = locate_vex(v2);
ArcBox *p = new ArcBox;
//*p = {i, j, xlist[j].firstin, xlist[i].firstout, NULL};
p->tail_vex = i;
p->head_vex = j;
p->hlink = xlist[j].firstin;
p->tlink = xlist[i].firstout;
p->info = info;
xlist[j].firstin = xlist[i].firstout = p;
}
}