东软学习小组成员:夜枫
测试案例
#include<iostream>
#include <stack>
#include<queue>
using namespace std;
stack<int> s;
stack<int> q;
const int N = 100;
int map[N][N];//矩阵
int ans[N];//顶点
int n, m;//n个顶点,m条边
bool vis[N] = {false};
int set[1000005];
int find(int x){
return x == set[x] ? x : (set[x] = find(set[x])); //递归查找集合的代表元素,含路径压缩。
}
void dfs1(int s){ //递归深搜
vis[s] = true;
for (int i = 1; i<=n; ++i){
if (!vis[i]){
dfs1(i);
}
}
}
bool judge(){ //判断是否所有点已被遍历过
for (int i = 1; i <= n; ++i)
if (!vis[i])
return false;
return true;
}
void dfs(int x, int isyou = 0){//默认无向图//isyou=1为有向图
s.push(x);
for (int i = 1; i <= n; ++i){
if (map[x][i] >= 1){//有边
map[x][i]--;
if (isyou == 0){//无向图对称
map[i][x]--;
}
dfs(i, isyou);
break;//一次
}
}
}
void fleury(int x,int isyou){
s.push(x);
int t = x;
while (!s.empty()){
int k = 0;
t = s.top();
s.pop();
for (int i = 1; i <= n; ++i){
if (map[t][i] >= 1){//有边
k = 1;
break;
}
}
if (k == 0){
q.push(t);
}
else{
dfs(t,isyou);
}
}
while (!q.empty()){
cout << q.top() << " ";
q.pop();
}
}
int main(){
cin >> n >> m;
int x, y,isyou;
int du[N];
int duc[N];
int sum = 0;
for (int i = 1; i < 1000005; ++i) //初始化个集合,数组值等于小标的点为根节点。
{
set[i] = i;
}
memset(du, 0, sizeof(du));
memset(vis, false, sizeof(vis));
memset(duc, 0, sizeof(duc));
memset(map, 0, sizeof(map));
cout << "是否为有向图 1.是,0,不是\n";
cin >> isyou;
for (int i = 1; i <= m; ++i){
cin >> x >> y;
int fx = find(x), fy = find(y);
set[fx] = fy;
map[x][y]++;
duc[x]++;
du[y]++;
if (isyou == 0){
map[y][x]++;
duc[y]++;
du[x]++;
}
}
int duflag;
int flag = 1;
for (int i = 1; i <= n; ++i){
if ((du[i] + duc[i]) % 2 == 1){
sum++;
if (du[i]<duc[i]){
flag = i;
}
}
}
cout << "sum " << sum << endl;
if (sum == 0){
int cnt = 0;
for (int i = 1; i <= n; ++i) //统计集合个数,即为连通分量个数,为一时,图联通。
{
if (set[i] == i)
{
++cnt;
}
}
if (cnt != 1){
cout << "你输入的是非欧拉图" << endl;
exit(0);
}
if (isyou == 1){//无向图
for (int i = 1; i <= n; ++i){
if (du[i] != duc[i]){
cout << "你输入的是非欧拉图" << endl;
exit(0);
}
}
}
if (isyou == 1){
for (int i = 1; i <= n; ++i){
if ((du[i]+duc[i])%2==1){
cout << "你输入的是非欧拉图" << endl;
exit(0);
}
}
}
}
if (sum == 2){
int cnt = 0;
for (int i = 1; i <= n; ++i) //统计集合个数,即为连通分量个数,为一时,图联通。
{
if (set[i] == i)
{
++cnt;
}
}
if (cnt == 1){
int min = 0, max = 0;
for (int i = 1; i <= n; ++i){
if ((du[i] + duc[i]) % 2 == 1){
if (du[i] < duc[i]){
min = 1;
}
if (du[i] > duc[i]){
max = 1;
}
}
}
if (min != 1 || max != 1){
cout << "你输入的是非欧拉图" << endl;
exit(0);
}
}
else{
cout << "你输入的是非欧拉图" << endl;
exit(0);
}
}
if (sum == 0 || sum == 2){
// cout << "开始" << endl;
fleury(flag,isyou);
}
return 0;
}
/*
案例一
4 4
0
1 2
2 3
3 4
4 1
案例二
6 7
1
2 1
2 4
4 3
3 2
1 6
6 5
5 1
*/