图的相关程序

来源:互联网 发布:python os.exec 编辑:程序博客网 时间:2024/06/01 18:12
//////////////////////////////////////////////////////////////                      Author: sky//Date:  2011.11.4//Content: 图的相关程序///////////////////////////////////////////////////////////#include <iostream>#include <string>using namespace std;#define  DEFAULT_SIZE 20#define  DEFAULT_WEIGHT 0bool visitable[DEFAULT_SIZE];// 标示节点是否被访问过////////////////////////////////////////////////////////////////////////////   摔角选手goodguy 和badguy的分配问题int color[DEFAULT_SIZE];//表示每个节点的颜色enum{goodGuy=1,badGuy=2};int colorFlag=goodGuy;bool IsDesignFlag=true;////////////////////////////////////////////////////////////////////////////打印两个点之间的线路(如果存在的话)bool IsFind=false;string Path="";// 记录所经过的线路struct Graph//本程序采用邻接矩阵方式存储图{Graph();bool Initialize(int vNum,int eNum,string nStr,int graType);int GetVertexLoc(char a) const;//得到节点 在途中的标号 ibool InsertNode(char beginNode,char endNode,int edgWeight);bool IsAcylic();//判断一个图是否是有向无环图(采用拓扑排序的方法)string node;//记录节点的字母表示int weight[DEFAULT_SIZE][DEFAULT_SIZE];int vertexNum,edgeNum,graphType;//分别代表 顶点个数 边的个数以及图的类型(1表示无向 2表示有向)};void DFS(Graph gra,int k=-1);//深度优先遍历(递归方法)void BFS(Graph gra);//广度优先遍历void IsDesign(Graph gra,int k=-1);//  实质是着色问题 即共两种颜色,图中相邻点不能为同一种颜色//通过此函数判断能否着色成功void PrintPath(Graph gra,char beginVertex,char endVertex);//k=-1表示 图中不存在该节点Graph::Graph(){node="";vertexNum=DEFAULT_SIZE;edgeNum=DEFAULT_SIZE;}bool Graph::Initialize(int vNum,int eNum,string nStr,int graType){if (nStr.length()!=vNum){cout<<"The Number of Node must be"<<vNum;return false;}vertexNum=vNum;edgeNum=eNum;graphType=graType;node=nStr;for (int i=0;i<vertexNum;i++){for (int j=0;j<vertexNum;j++){weight[i][j]=DEFAULT_WEIGHT;//权重初始化为0  同时也可以表示两个顶点不可达}visitable[i]=false;//初始化访问节点 为false}return true;}int Graph::GetVertexLoc(char a)const{for (int i=0;i<vertexNum;i++){if (node[i]==a)return i;}return -1;}bool Graph::InsertNode(char beginNode,char endNode,int edgWeight){int i=GetVertexLoc(beginNode);int j=GetVertexLoc(endNode);if (i==-1||j==-1){cout<<"Node is not in Graph"<<endl;return false;}weight[i][j]=edgWeight;//表示有向图if (graphType==1){weight[j][i]=weight[i][j];//表示无向图}return true;}bool Graph::IsAcylic()//使用拓扑排序判断有向图是否存在环{if (graphType!=2)//判断是否是有向图{return false;}bool checked[DEFAULT_SIZE];for (int i=0;i<vertexNum;i++){checked[i]=false;}int inDegree=0;//inDegree 表示入度的个数for(int i=0;i<vertexNum;i++){checked[i]=false;for (int j=0;j<vertexNum;j++){if(weight[j][i]!=DEFAULT_WEIGHT&&(checked[i]==false)&&(checked[j]==false))inDegree++;}if (inDegree==0){checked[i]=true;}inDegree=0;}for(int i=vertexNum-1;i>=0;i--){for (int j=0;j<vertexNum;j++){if(weight[j][i]!=DEFAULT_WEIGHT&&(checked[i]==false)&&(checked[j]==false))inDegree++;}if (inDegree==0){checked[i]=true;}inDegree=0;}for(int i=0;i<vertexNum;i++){if (checked[i]==false){return false;//如果仍然存在没有被访问的点 说明存在环}}return true;}void DFS(Graph gra,int k){if(k==-1)//表示第一次执行 实质 是递归的最上层循环{for (int j=0;j<gra.vertexNum;j++){if (!visitable[j]){DFS(gra,j);}}}else{cout<<gra.node[k]<<"";//此处因为第一次执行的时候肯定visitable==falsevisitable[k]=true;for (int j=0;j<gra.vertexNum;j++){bool judge=(gra.weight[k][j]!=DEFAULT_WEIGHT)&&(visitable[j]==false);if (judge){DFS(gra,j);}}}}void BFS(Graph gra){for (int i=0;i<gra.vertexNum;i++){if (!visitable[i]){cout<<gra.node[i]<<"";visitable[i]=true;for (int j=0;j<gra.vertexNum;j++){if ((gra.weight[i][j]!=DEFAULT_WEIGHT)&&(!visitable[j])){cout<<gra.node[j]<<"";visitable[j]=true;}}}}}void IsDesign(Graph gra,int k)//着色问题的核心函数{if(k==-1)//表示第一次执行{bool aloneVertexFlag=false;for (int j=0;j<gra.vertexNum;j++){if (visitable[j]==false){IsDesign(gra,j);}}}else{visitable[k]=true;color[k]=colorFlag;for (int j=0;j<gra.vertexNum;j++){if (gra.weight[k][j]!=DEFAULT_WEIGHT){if (visitable[j]==false){if (color[k]==goodGuy)//每遍历到一个节点之后 就改变一次colorFlag{colorFlag=badGuy;} else{colorFlag=goodGuy;}IsDesign(gra,j);}else   //否则的话 就表示 两个点有连线 而且已经被访问过了,所以可以用来检测是否能涂色{if(color[k]==color[j]){IsDesignFlag=false;}}}}}}void PrintPath(Graph gra,char beginVertex,char endVertex)//查找路线的核心函数{int k=gra.GetVertexLoc(beginVertex);//找到起始顶点 在邻接矩阵中的位置if (k==-1||(gra.GetVertexLoc(endVertex)==-1)){cout<<"illegal Vertex"<<endl;return;}visitable[k]=true;Path+=gra.node[k];Path+="-->";if(endVertex==gra.node[k]){IsFind=true;return;}for (int j=0;j<gra.vertexNum;j++){if((gra.weight[k][j]!=DEFAULT_WEIGHT) &&(visitable[j]==false)){PrintPath(gra,gra.node[j],endVertex);if (IsFind==true)return;}}if (IsFind==false)//如果没找到 就取消线路上的节点{Path=Path.substr(0,Path.size()-4);}}void FirstProblem()//{int verNum=0,edgNum=0,graType=1;string nodeStr;Graph gra;cout<<"\n\n\n\nInput Vertex Number: ";cin>>verNum;cout<<"Input Edge Number: "; cin>>edgNum;cout<<"Input Node String with no space(eg, ABCDEF): ";cin>>nodeStr;if(!gra.Initialize(verNum,edgNum,nodeStr,graType)){cout<<"Initialization error!";return ;}for (int i=0;i<edgNum;i++){char a,b;int eweight=1;//此处设定了默认的权重为1 因为不涉及权重 固不输入权重cout<<"\nPlease Input edge "<<(i+1)<<" :";cin>>a>>b;if(!gra.InsertNode(a,b,eweight)) return;}IsDesign(gra);cout<<"\nIs possible to Design? The answer is :\n";if(IsDesignFlag){cout<<"\t\t\tYes, you can get the answer like that"<<endl;for (int i=0;i<verNum;i++){cout<<'\n\t'<<gra.node[i]<<" locates ";if (color[i]==1){cout<<" goodGuy"<<endl;}else{cout<<" badGuy"<<endl;}}}else{cout<<"\n!No solution"<<endl;}}void SencondProblem()//{int verNum=0,edgNum=0,graType=2;//2表示有向图string nodeStr;Graph gra;cout<<"\n\n\n\nInput Vertex Number: ";cin>>verNum;cout<<"Input Edge Number: "; cin>>edgNum;cout<<"Input Node String with no space(eg, ABCDEF): ";cin>>nodeStr;if(!gra.Initialize(verNum,edgNum,nodeStr,graType)){cout<<"Initialization error!";return ;}for (int i=0;i<edgNum;i++){char a,b;int eweight=1;//此处设定了默认的权重为1 因为不涉及权重 固不输入权重cout<<"\nPlease Input edge "<<(i+1)<<" :";cin>>a>>b;if(!gra.InsertNode(a,b,eweight)) return ;}if(gra.IsAcylic()==false)//判断是否为有向无环图{cout<<" Sorry, This is not a directed acylic Graph ";return ;}char beginVertex,endVertex;cout<<"\n\nInput two Vertex: ";cin>>beginVertex>>endVertex;PrintPath(gra,beginVertex,endVertex);if (IsFind){Path=Path.substr(0,Path.size()-3);cout<<"The Path is : "<<Path;}else{cout<<"\n!Sorry, Two Vertex can't communication";}}int main(int agrc,char* argv[]){Graph gra=InputGraph();cout<<"Print by DFS:"<<endl;DFS(gra);cout<<"\nPrint by BFS:"<<endl;for(int i=0;i<gra.vertexNum;i++)visitable[i]=false;BFS(gra);cout<<"The first Problem :\n";FirstProblem();cout<<"The second Problem :\n";SencondProblem();return 0;}


 

原创粉丝点击