(一)九度上一个练习题
给定一个无向图和其中的所有边,判断这个图是否所有顶点都是连通的。
每组数据的第一行是两个整数 n 和 m(0<=n<=1000)。n 表示图的顶点数目,m 表示图中边的数目。如果 n 为 0 表示输入结束。随后有 m 行数据,每行有两个值 x 和 y(0<x, y <=n),表示顶点 x 和 y 相连,顶点的编号从 1 开始计算。输入不保证这些边是否重复。
对于每组输入数据,如果所有顶点都是连通的,输出"YES",否则输出"NO"。
4 3 1 2 2 3 3 2 3 2 1 2 2 3 0 0
NO YES
(二)判断图是否是连通的,可以通过深度优先遍历的方法判断。具体实现为:在图中选定任一一个顶点,对该顶点进行深度优先遍历,如果在这个遍历过程中所有的顶点都被遍历到,则该图为连通;反之,若存在没有被遍历到的顶点,则说明该图是非连通的。实现代码如下(针对无向图,使用邻接表结构):
#include <iostream> #include <string.h> using namespace std; #define MAX_NODE 1000 typedef struct ArcNode { int adjvex;//弧指向的节点的值(点的标号) ArcNode* next;//指向下一条弧 ArcNode(int value) { adjvex = value; next = NULL; } };//邻接表节点 typedef struct { int vexdata; //头节点的标号 struct ArcNode* firstarc;//第一个邻接表节点的地址 }VexNode, AdjList[MAX_NODE];//头结点 typedef struct { AdjList vexNodes; int vexNum; int arcNum;//当前节点数目和弧数 }GraphWithAL;//邻接表表示的图 //检测要输入的边是否已经存在,针对无向图 bool CheckArcIsExist(GraphWithAL* G, int v1, int v2) { ArcNode* temp = G->vexNodes[v1-1].firstarc; while(temp!=NULL) { if(temp->adjvex == v2) return true; temp = temp->next; } return false; } //创建图,vexNum代表顶点的个数,arcNum代表边的个数,isUnDirected代表的是 是否是无向图 void CreateGraph(GraphWithAL* G, int vexNum, int arcNum, bool isUnDirected) { memset(G, 0 ,sizeof(GraphWithAL)); //初始化头结点 int i = 0; for(i=0; i<vexNum; ++i) { G->vexNum = vexNum; G->vexNodes[i].firstarc = NULL; G->vexNodes[i].vexdata = i+1;//从1开始计算顶点 } //初始化边 for(i=0; i<arcNum; ++i) { //输入边的顶点和尾点 int v1, v2; cin>>v1>>v2; if(CheckArcIsExist(G, v1, v2)) continue; ArcNode* arcNode = new ArcNode(v2); //还需要检验边是否已经存在,这里没有检验 arcNode->next = G->vexNodes[v1-1].firstarc; G->vexNodes[v1-1].firstarc = arcNode; G->arcNum++; if(isUnDirected) { ArcNode* arcNode = new ArcNode(v1); //还需要检验边是否已经存在,这里没有检验 arcNode->next = G->vexNodes[v2-1].firstarc; G->vexNodes[v2-1].firstarc = arcNode; } } } //对第vex个顶点递归的做深度优先遍历, 若遍历到该顶点则将visit数组中对应的值置为true void DFS(GraphWithAL* G, int vex, bool* visit) { //cout<<vex<<endl; visit[vex-1] = true; ArcNode* temp = G->vexNodes[vex-1].firstarc; if(temp == NULL) { //cout<<vex<<"->null"<<endl; return ; } while(temp != NULL) { if(!visit[temp->adjvex-1]) { //cout<<vex<<"->"<<temp->adjvex<<endl; visit[temp->adjvex-1] = true; DFS(G, temp->adjvex, visit); } temp = temp->next; } } //深度优先遍历 图 void DFS_Visit(GraphWithAL* G) { bool* visit = new bool[G->vexNum]; memset(visit, 0, G->vexNum); int i=0; for(i=0; i<G->vexNum; ++i) { if(!visit[i]) DFS(G, i+1, visit); } } //检测图是否是连通的 bool CheckGraphIsConnected(GraphWithAL* G) { bool* visit = new bool[G->vexNum]; memset(visit, 0, G->vexNum); DFS(G, 1, visit); int i=0; for(i=0; i<G.vexNum; ++i) { if(!visit[i]) return true; } return false; } int main() { GraphWithAL G; int n, m; while(cin>>n>>m) { if(n==0) break; CreateGraph(&G, n, m, true); //DFS_Visit(&G); //检测图是否连通 bool flag = CheckGraphIsConnected(&G); if(flag) cout<<"NO"<<endl; else cout<<"YES"<<endl; } return 0; }