您的位置:首页 > 其它

图论算法---- 一笔画问题(欧拉路)

2016-10-10 12:58 561 查看

一、题目描述

题目描述

对给定的一个无向图,判断能否一笔画出。若能,输出一笔画的先后顺序,否则输出“No Solution!”

所谓一笔画出,即每条边仅走一次,每个顶点可以多次经过。

输出字典序最小的一笔画顺序。

输入

第1行:1个整数n,表示图的顶点数(n<=100)

接下来n行,每行n个数,表示图的邻接矩阵

输出

第1行:一笔画的先后顺序,每个顶点之间用一个空格分开

样例输入

样例一

3

0 1 1 

1 0 1 

1 1 0 

样例二:

7

0 1 0 1 1 0 1 

1 0 1 0 0 0 0 

0 1 0 1 0 0 0 

1 0 1 0 0 0 0 

1 0 0 0 0 1 0 

0 0 0 0 1 0 1 

1 0 0 0 0 1 0 

样例输出

样例一:

1 2 3 1

样例二:

1 2 3 4 1 5 6 7 1

二、分析

我们先要找到数据中的奇数点,如果奇数点的个数>2或者等于1,就输出“No Solution!”,
如果没有奇数点,就从1开始进行dfs(),如果奇数点有两个,就从小的奇数点开始进行dfs()。
#include<cstdio>
int a[105][105],n,as[105],k;
bool vis[105][105];
void dfs(int s){
int i;
for(i=1;i<=n;i++){
if(a[s][i]==1){
a[s][i]=0;//因为是一次性的dfs(),所以不用回溯。
a[i][s]=0;
dfs(i);
}
}
k++;
as[k]=s;//存答案
}
int main()
{
//freopen("euler-circuit.in","r",stdin);
//freopen("euler-circuit.out","w",stdout);
int i,j,sum1=0,sum2=0,f;//sum1是来存一行的度,sum2是来存奇数点的个数
f=1;
scanf("%d",&n);
for(i=1;i<=n;i++){
sum1=0;
for(j=1;j<=n;j++){
scanf("%d",&a[i][j]);
if(a[i][j]==1)
sum1++;
}
if(sum1%2==1){
if(sum2==0)
f=i;
sum2++;
}
sum1=0;
}
if(sum2>2||sum2==1){
printf("No Solution!");
return 0;
}
dfs(f);
for(i=k;i>=1;i--){//因为函数是先存入最后的数,所以要倒叙输出。
printf("%d ",as[i]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息