题目大意
给定N个顶点M条边的无向图,判断该图是Eulerian,semi-Eulerian还是non-Eulerian,并输出每一个顶点的度。
算法思路
首先得理清几个概念
- Eulerian path:恰好访问图中所有顶点的路径
- Eulerian circuit:Eulerian path的起点和终点相同
- Eulerian: 在一个连通图中所有顶点的度为偶数
- semi-Eulerian:连通图含有Eulerian path但没有 Eulerian circuit,即连通图中只有两个顶点的度为奇数
- non-Eulerian:既不是Eulerian也不是semi-Eulerian
对于顶点的度直接使用degree数组统计输出即可,然后我们判断当前图是否是连通图,判断方法就是从任一起点使用深度优先搜索,如果该连通分量的顶点数目和N相同,就说明该图连通,否则就不是连通图,输出Non-Eulerian,然后再统计每一个顶点的度是否是偶数,如果都是偶数,输出Eulerian,如果只有两个顶点的度为奇数,输出Semi-Eulerian,否则输出Non-Eulerian。
提交结果
AC代码
#include <cstdio>
using namespace std;
int G[505][505];
int degree[505];// 每一个顶点的度
bool visited[505];// 访问标记数组
int cnt = 0;// 顶点为1的连通分量的顶点数目
int n,m;
void DFS(int start){
visited[start] = true;
++cnt;
for(int i=1;i<=n;++i){
if(!visited[i]&&G[start][i]!=0){
DFS(i);
}
}
}
void printDegree(){
for(int i=1;i<=n;++i){
printf("%d",degree[i]);
if(i<n) printf(" ");
}
printf("\n");
}
int main() {
scanf("%d %d",&n,&m);
for(int i=0;i<m;++i){
int a,b;
scanf("%d %d",&a,&b);
G[a][b] = G[b][a] = 1;
++degree[a];
++degree[b];
}
// 统计从顶点1出发的连通分量的顶点数
DFS(1);
printDegree();
if(cnt!=n){
// 该图不连通
printf("Non-Eulerian");
}else{
int evenDegree = 0;// 度为偶数的顶点个数
for(int i=1;i<=n;++i){
if(degree[i]%2==0){
++evenDegree;
}
}
if(evenDegree==n){
printf("Eulerian");
}else if(evenDegree==n-2){
printf("Semi-Eulerian");
}else{
printf("Non-Eulerian");
}
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。