CCF-CSP—2015.12.—4 送货(欧拉路)80 分 题解

题目来源:

点击打开链接

题目描述:

问题描述
  为了增加公司收入,F公司新开设了物流业务。由于F公司在业界的良好口碑,物流业务一开通即受到了消费者的欢迎,物流业务马上遍及了城市的每条街道。然而,F公司现在只安排了小明一个人负责所有街道的服务。
  任务虽然繁重,但是小明有足够的信心,他拿到了城市的地图,准备研究最好的方案。城市中有 n个交叉路口, m条街道连接在这些交叉路口之间,每条街道的首尾都正好连接着一个交叉路口。除开街道的首尾端点,街道不会在其他位置与其他街道相交。每个交叉路口都至少连接着一条街道,有的交叉路口可能只连接着一条或两条街道。
  小明希望设计一个方案,从编号为1的交叉路口出发,每次必须沿街道去往街道另一端的路口,再从新的路口出发去往下一个路口,直到所有的街道都经过了正好一次。
输入格式
  输入的第一行包含两个整数 nm,表示交叉路口的数量和街道的数量,交叉路口从1到 n标号。
  接下来 m行,每行两个整数 ab,表示和标号为 a的交叉路口和标号为 b的交叉路口之间有一条街道,街道是双向的,小明可以从任意一端走向另一端。两个路口之间最多有一条街道。
输出格式
  如果小明可以经过每条街道正好一次,则输出一行包含 m+1个整数 p 1p 2p 3, ...,  pm +1,表示小明经过的路口的顺序,相邻两个整数之间用一个空格分隔。如果有多种方案满足条件,则输出字典序最小的一种方案,即首先保证 p 1最小, p 1最小的前提下再保证 p 2最小,依此类推。
  如果不存在方案使得小明经过每条街道正好一次,则输出一个整数-1。
样例输入
4 5
1 2
1 3
1 4
2 4
3 4
样例输出
1 2 4 1 3 4
样例说明
  城市的地图和小明的路径如下图所示。
样例输入
4 6
1 2
1 3
1 4
2 4
3 4
2 3
样例输出
-1
样例说明
  城市的地图如下图所示,不存在满足条件的路径。
评测用例规模与约定
  前30%的评测用例满足:1 ≤  n ≤ 10,  n-1 ≤  m ≤ 20。
  前50%的评测用例满足:1 ≤  n ≤ 100,  n-1 ≤  m ≤ 10000。
  所有评测用例满足:1 ≤  n ≤ 10000, n-1 ≤  m ≤ 100000。

解题思路:

     这题就是一题欧拉路判断,无向图欧拉路的条件是:1.所有点的度数都为偶数,2.有且只有两个点度数为奇数

     本题必须要从1出发,而且要输出字典序最小的,所以用dfs实现的时候要先排序,而且dfs之前要先用并查集判断一下连通性。因为点比较少可以用二维数组对边判重。不过不知道为什么,交上去就80~~~。 

     希望给我大神指点。   


代码:

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
int n,m;
vector<int>E[10010];
int ds[10010];
bool jl[10010][10010];
int father[10010];
stack<int>s;
void init()
{
	for(int i=1;i<=n;i++)
	father[i]=i;
	return ;
}
int fi(int x)
{
	if(x==father[x])return x;
	else return father[x]=fi(father[x]);
}
bool same(int x,int y)
{
	if(fi(x)==fi(y))return 1;
	else return 0;
}
void Union(int x,int y)
{
	int u=fi(x),v=fi(y);
	if(u==v)return ;
	father[u]=v;
}
void dfs(int u)
{
	int v;
	for(int i=0;i<E[u].size();i++)
	{
		v=E[u][i];
		if(!jl[u][v]){
			jl[v][u]=1;
			jl[u][v]=1;
			dfs(v);
			s.push(v);
		}	
	}
}  
int main()
{
	
	memset(ds,0,sizeof(ds));
	memset(jl,0,sizeof(jl));
	scanf("%d%d",&n,&m);
	init();
	for(int i=1;i<=m;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		if(!same(a,b)){
			Union(a,b);
		}
		E[a].push_back(b);
		E[b].push_back(a);
		ds[a]++;ds[b]++;
	}
	int pd=0;
	for(int i=1;i<=n;i++)
	{
		if(ds[i]%2!=0)pd++;
		sort(E[i].begin(),E[i].end());
	}
	if(pd>2||pd==1){
		cout<<"-1"<<endl;
		return 0;
	}
	if(pd==2&&E[1].size()%2==0){
		cout<<"-1"<<endl;
		return 0;
	} 
    for(int i=1;i<=n;i++)  
    {  
        if(!same(i,1))  
        {  
            cout << "-1";  
            return 0;  
        }  
    }  
	dfs(1);
	cout<<1;
	while(!s.empty())
	{
		cout<<" "<<s.top();
		s.pop();
	}
	return 0;
}



猜你喜欢

转载自blog.csdn.net/qq_40400202/article/details/80932974