欧拉图模板

欧拉路径模板

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+99;
int n,m,tot;

clock_t start,finish;//
double totaltime;//

inline void Start()
{
    
    start=clock();//
}

inline void Finish()
{
	finish=clock();//
   	totaltime=(double)(finish-start);//
   	cout<<"\n此程序的运行时间为"<<totaltime<<"ms!"<<endl;//
}

namespace oula
{
	struct Edge//边 
	{
		int to,id;
	};
	vector<Edge>d[maxn];
	int in[maxn],out[maxn];
	stack<int> S;
	int vis[maxn];
	int fa[maxn];
	int orz;
	
	inline void init()//初始化 
	{
		orz=n;
		for(int i=0;i<maxn;i++)d[i].clear();
		memset(in,0,sizeof in);
		memset(out,0,sizeof out);
		memset(vis,0,sizeof vis);
		for(int i=1;i<=n;i++)fa[i]=i;
	}
	
	int get(int x)
	{
    	if (fa[x] == x)return x;
    	return fa[x] = get(fa[x]);
	}

	void merge(int x, int y)
	{
    	x = get(x);
    	y = get(y);
    	if (x != y)
    	{
        	fa[y] = x;
        	orz--;
    	}
	}
	
	inline void add(int u,int v,int id,int op)//建图 
	{
		d[u].push_back({v,id});
		if(op==2)d[v].push_back({u,id});
		out[u]++;
        in[v]++;
        merge(u,v);
	}

	void dfs(int u){
		for(int i=0;i<d[u].size();i++){
			Edge p = d[u][i];
			if(!vis[p.id]){
				vis[p.id] = true;
				dfs(p.to);
			}
		}
		S.push(u);
	}
	
	inline void Hierholzer()
	{
		while(!S.empty())
		{
			cout<<S.top()<<" ";
			S.pop();
		}
	}
	
	inline void js(int op)//判断欧拉路径(通路||回路) 
	{
		int cnt=1;
		
		if (orz > 1)
    	{
        	printf("No\n");
        	exit(0);
    	}
    	
		if(op==1)
		{
			int cntin=0,cntout=0;
			for (int i = 1; i <= n; i++)
    		{
        		if (out[i] - in[i] == 1)
            		cntout++,cnt=i;
        		else if (out[i] - in[i] == -1)
            		cntin++;
        		else if (out[i] != in[i])
        		{
            		printf("No\n");
            		//return false;
            		exit(0);
        		}
    		}
    		if (cntout == 0 && cntin == 0)
    		{
				printf("Euler loop\n");
				dfs(1);
				//return true;
			}
    		else if (cntout == 1 && cntin == 1)
        	{
				printf("Euler path\n");
				dfs(cnt);
				//return true;
			}
    		else
        	{
				printf("No\n");
        		exit(0);
    		}
    	}
    	else
    	{
    		int euler=0;
			for (int i = 1; i <= n; i++)
    		{
        		if ((in[i]+out[i]) & 1)
            		euler++,cnt=i;
    		}
    		if (orz > 1)
    		{
        		printf("No\n");
        		exit(0);
    		}
    		if(euler == 0)
    		{
    			printf("Euler loop\n");
    			dfs(1);
			}
			else if(euler==2)
			{
				printf("Euler path\n");
				dfs(cnt);
			}
    		else
    		{
        		printf("No\n");
        		exit(0);
        	}
		}
    	Hierholzer();
	}
	
}

using namespace oula;

int main()//op: 1有向图  2无向图 
{
	cin>>n>>m;
	init();
	orz=n;
	//Start();
	for(int i=1;i<=m;i++)
	{
		int u,v;
		cin>>u>>v;
		add(u,v,i,1);
	}
	js(1);
	
	//Finish();
}
posted @ 2021-04-23 19:12  蒟蒻orz  阅读(3)  评论(0编辑  收藏  举报  来源