知识回顾
DFS伪代码:
DFS(u)//访问顶点u vis[u]=true;//设置u已被访问 for(从u出发能到达的所有顶点v)//枚举从u出发可以到达的所有顶点v if(vis[v]==false) //如果v未被访问 DFS(v);//递归访问v结点 } DFSTrave(G){ for(G的所有顶点u)//对G的所有顶点u if vis[u]==false //如果u未被访问 DFS(U);//访问u所在的连通块 }
(1)如果是一个连通图,则只需要一次DFS即可完成遍历。
(2)可以用DFS判断一个无向图是否为连通图。
有1个点没过(20分)
#include<stdlib.h> #include<vector> #include<iostream> using namespace std; vector<vector<int>>v1; //v[i]即为i号结点所连接的边 vector<bool>visit;//判断该结点是否访问过,dfs用到 int cnt=0; void dfs(int index){ visit[index]=true; cnt++; for(int i=0;i<v1[index].size();i++) //for循环访问index号点出发可以到达的所有顶点 if(visit[ v1[index][i] ]==false) dfs(v1[index][i]); //若该点未被访问过则dfs递归访问 } int main(){ int vernum,edgenum; scanf("%d%d",&vernum,&edgenum);//点数,边数 v1.resize(vernum+1); visit.resize(edgenum+1); int a,b; for(int i=1;i<=edgenum;i++){//遍历所有的边(存储) scanf("%d%d",&a,&b);//存储边 v1[a].push_back(b); v1[b].push_back(a); } dfs(1);//从1号结点开始 //判断环节 int even=0;//统计度为偶数的个数 for(int i=1;i<=vernum;i++){ //遍历所有点的度&统计度为偶数的点个数 if(i!=1) cout<<" "; //注意每个点的度之间有空格 cout<<v1[i].size();//按点序输出每个点的度 if(v1[i].size()%2==0){//这里注意v[i].size()这种写法 even++; } } cout<<endl; if((even==vernum)&&(cnt=vernum)) printf("Eulerian"); else if((even==vernum-2)&&(cnt=vernum)) printf("Semi-Eulerian"); else printf("Non-Eulerian"); system("pause"); }
AC代码
1.
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<math.h> #include<string.h> #include<algorithm> #include<map> #include<vector> #include<queue> using namespace std; vector<vector<int>>v; //v[i].size()表示每个结点的度,邻接表存储图 vector<bool>visit; int cnt=0; //用dfs判断连通性 void dfs(int index){ visit[index]=true;//表示index点被访问过 cnt++;//最后的cnt为n即表示为连通图 for(int i=0;i<v[index].size();i++)//小于size,非无递归边界 if(visit[v[index][i]]==false) dfs(v[index][i]); //若该点为被访问过则dfs递归访问 } int main(){ int n,m,a,b,even=0; scanf("%d%d",&n,&m);//点数n 边数m v.resize(n+1);//初值为0 visit.resize(n+1); //v.resize(n);//初值为0 //visit.resize(n); for(int i=0;i<m;i++){ scanf("%d%d",&a,&b);//存储边 v[a].push_back(b);//存储a点的度 v[b].push_back(a);//存储b点的度 } for(int i=1;i<=n;i++){ if(i !=1) printf(" "); printf("%d",v[i].size());//输出每个结点的度 if(v[i].size()%2==0) even++;//累计度为偶数的个数 } printf("\n"); dfs(1);//从结点1开始dfs if(even==n&&cnt==n) //若全是度为偶数的结点&& printf("Eulerian"); else if(even==n-2&&cnt==n) printf("Semi-Eulerian"); else printf("Non-Eulerian"); system("pause"); return 0; }