原题目: 1126 Eulerian Path (25 分).
题意
如果⼀一个连通图的所有结点的度都是偶数,那么它就是Eulerian,如果除了了两个结点的度是奇数其他都是偶数,那么它就是Semi-Eulerian,否则就是Non-Eulerian。
分析
- 存储:用邻接表存储无向图。
- 先 判断连通性:用DFS从结点1开始遍历,注意标记已遍历过的结点,并用计数器 cnt 计算遍历过的结点数,与总顶点数对比即可知是否连通图。
- 判断Eulerian:遍历每个结点的度,即每个结点 i 的 v[i].size()。
CODE
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> v;
vector<bool> visit;
int cnt = 0;
void DFS(int index);
int main()
{
int n, m, a, b, even = 0;
cin >> n >> m;
v.resize(n+1);
visit.resize(n+1);
for ( int i=0; i<m; i++ ){ //用邻接表存储无向图
cin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
}
for ( int i=1; i<=n; i++ ){
if ( i!=1 ) printf(" ");
printf("%d", v[i].size());
if ( v[i].size()%2==0 ) even++;
}
cout << endl;
//深搜判断连通性
DFS(1);
if ( even==n && cnt==n )
printf("Eulerian");
else if ( even==n-2 && cnt==n )
printf("Semi-Eulerian");
else
printf("Non-Eulerian");
return 0;
}
void DFS(int index){
visit[index] = true; //标记遍历过的点
cnt++; //记录遍历过的点数
for ( int i=0; i<v[index].size(); i++ ){
if (visit[v[index][i]]==false )
DFS(v[index][i]); //深搜没遍历过的点
}
}