【图】一笔画
一筆畫問題(euler-circuit.cpp)
題目描述對給定的一個無向圖,判斷能否一筆畫出。若能,輸出一筆畫的先后順序,否則輸出“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個肯定是不行的,直接“No Solution!”,否則就從其中一個出發,沒有的話就從偶數點開始,注意要字典序最小。
遞歸就一個參數——當前到哪個點了,然后從1循環到當前,如果可以到就進入,注意此時要將此路封閉,出來時存一下就可以了。
代碼:
#include<cstdio> int a[105][105],ans[10005],p; int n,f,b=1,al; void m(int x) {for(int i=1;i<=n;i++)if(a[x][i]==1){a[x][i]=0;a[i][x]=0;//x點到i點和i點到x點都要清0,以免重復遞歸m(i);}ans[++al]=x;//記錄路徑 } int main() {freopen("euler-circuit.in","r",stdin);freopen("euler-circuit.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++){p=0;//存當前點的度for(int j=1;j<=n;j++){scanf("%d",&a[i][j]);if(a[i][j]==1)p++;//如果有聯通,度++}if(p%2==1)//度為奇數(奇數點){if(f==0)//f用來看是否為第一個奇數點,順便統計有多少個奇數點b=i;//b是存開始點f++;}}if(f>2)//奇數點大于2便一定無法完成{printf("No Solution!");return 0;}m(b);//開始遞歸printf("%d",ans[al]);for(int i=al-1;i>=1;i--)printf(" %d",ans[i]);return 0; }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?By WZY
轉載于:https://www.cnblogs.com/LinqiongTaoist/p/7203761.html
總結
- 上一篇: apache 配置rewrite模块,U
- 下一篇: vs2015安装与单元测试以及经过优化的