ccf-送货

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/imotolove/article/details/80788451
利用dfs输出欧拉路,用sort保证字典序最小,并查集判联通,再考虑点的度数确定是否存在欧拉路
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool vis[10001][10001];
vector<int>g[10001];
int p[10001],d[10001],r[200001];
int s=0;
int findset(int x) //并查集 
{
	if(x==p[x])
	return x;
	else
	return p[x]=findset(p[x]);
}
void dfs(int k) //欧拉路 
{	
	for(int i=0;i<g[k].size();++i)
	{
		int y=g[k][i];
		if(!vis[k][y])
		{
			vis[k][y]=vis[y][k]=true;
			dfs(y);
		}
	}
	r[s++]=k;//模拟栈 
}
int main()
{
	int n,m,a,b,cnt,du=0;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	p[i]=i;
	for(int i=0;i<m;i++)
	{
		cin>>a>>b;
		d[a]++; d[b]++;
		g[a].push_back(b);
		g[b].push_back(a);
		int x=findset(a); //并查集 
		int y=findset(b);
		if(x!=y)
		p[x]=y;	
	}
	for(int i=1;i<=n;i++)
	{
	  sort(g[i].begin(),g[i].end());	//边排序,保证字典序最小 
	   if(p[i]==i)    //联通分量,大于1表示图不连通 
	    cnt++;
	   if(d[i]%2==1)  //点的度数为奇数,欧拉图只能没有奇数点或者两个 
	    du++;
	}
	dfs(1);
  	if(cnt!=1||(du!=0&&du!=2)||(du==2&&d[1]%2==0))
  	  cout<<-1<<endl;
  	else
  	{
  		for(int i=s-1;i>=0;i--)
    	cout<<r[i]<<" ";
	}
   return 0;	
} 

猜你喜欢

转载自blog.csdn.net/imotolove/article/details/80788451