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

一、题目描述

题目描述
对给定的一个无向图,判断能否一笔画出。若能,输出一笔画的先后顺序,否则输出“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
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]);
	}
}











你可能感兴趣的:(C++,图论,搜索)