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";
}
}
}