1. 程式人生 > >圖論演算法---- 一筆畫問題(尤拉路)

圖論演算法---- 一筆畫問題(尤拉路)

一、題目描述

題目描述
對給定的一個無向圖,判斷能否一筆畫出。若能,輸出一筆畫的先後順序,否則輸出“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]);
	}
}