圖論演算法---- 一筆畫問題(尤拉路)
阿新 • • 發佈:2019-02-13
一、題目描述
題目描述對給定的一個無向圖,判斷能否一筆畫出。若能,輸出一筆畫的先後順序,否則輸出“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]); } }