1001: 一筆畫
Time Limit: 1 Sec Memory Limit: 128 MB 64bit IO Format: %lld
Submitted: 61 Accepted: 11
[Submit][Status][Web Board]
Description
對給定的一個無向圖,判斷能否一筆畫出。若能,輸出一筆畫的先後順序,否則輸出“No Solution!”
所謂一筆畫出,即每條邊僅走一次,每個頂點可以多次經過。
輸出字典序最小的一筆畫順序。
Input
包含多組測試數據。
第一行n,m,有n個點,m條邊,以下m行描述每條邊連接的兩點。(n<=100)
Output
每組測試數據佔一行。一筆畫的先後順序,每個頂點之間用一個空格分開。
如果不能完成一筆畫,則輸出“No Solution!”
Sample Input
3 3
1 2
1 3
2 3
5 5
1 2
2 3
3 4
4 5
5 1
Sample Output
1 2 3 1
1 2 3 4 5 1
[Submit][Status][Web Board]
一開始還傻fufu地去定義結構體,其實這個題就是一個數學問題
歐拉七橋問題:
一個圖形可以一筆畫,必須滿足如下兩個條件:
1. 圖形必須是連通的。
2. 途中的“奇點”個數是0或2。(奇點即度數爲奇數的點)
所以思路就是:
先去判斷奇點地個數,若爲0或2個就DFS去找路
對於字典序最小的話,若是奇點數爲0個就從DFS(0)開始,若是奇點數爲2個就從第一個奇點數去DFS,因爲想要一筆畫出就要從奇點開始走.
以下爲代碼
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
#define MAX_ARCS_NUM 200
#define MAX_VERTEX_NUM 200
int Graph[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int Graph_VexNum;
int Graph_ArcsNum;
int tot;
int Path[MAX_ARCS_NUM];
int Degree[MAX_VERTEX_NUM];
void DFS(int x){
int i;
for(i=0;i<Graph_VexNum;i++){
if(Graph[x][i]){
Graph[x][i] = 0;
Graph[i][x] = 0;
DFS(i);
}
}
Path[tot] = x;
tot++;
}
int main(){
int i,j;
int start;
int end;
int flag,min;
while(cin>>Graph_VexNum>>Graph_ArcsNum){
min=0;
memset(Path,0,sizeof(Path));
memset(Graph,0,sizeof(Graph));
memset(Degree,0,sizeof(Degree));
for( i=0;i<Graph_ArcsNum;i++){
cin>>start>>end;
Graph[start-1][end-1] = 1;
Graph[end-1][start-1] = 1;
Degree[start-1]++;
Degree[end-1]++;
}
flag=0;tot=0;
for( i=0;i<Graph_VexNum;i++){
if(Degree[i]%2){
if(flag==0)
{
min = i;
}
flag++;
}
}
if(flag==0||flag==2){
DFS(min);
for(i=tot-1;i>=1;i--)
cout<<Path[i]+1<<" ";
cout<<Path[0]+1<<endl;
}
else{
cout<<"No Solution!\n";
}
}
}