• 欧拉回路&欧拉通路问题总结


    欧拉回路

    定义

    经过图中所有边恰好一次,并回到原点的路径。

    定理

    无向图(G)存在欧拉回路的充要条件是(G)中无奇数度数的节点。

    有向图(G)存在欧拉回路的充要条件是(G)联通且对于所有点(P in G)有其入度等于其出度。

    算法

    时间复杂度(O(n))

    先指定一个点作为起始点(S),进行(dfs),边走边删边。并压入栈中

    如果走到一个点了无路可走了就退回来。

    最后倒序输出栈就是以S为起点与终点的欧拉回路

    模板题 (uoj117)

    注意重边和自环是有用的。

    并且要用当前弧优化,不然会超时

    (Code)

    /*
    @Date    : 2019-07-23 18:05:40
    @Author  : Adscn (adscn@qq.com)
    @Link    : https://www.cnblogs.com/LLCSBlog
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define IL inline
    #define RG register
    #define gi getint()
    #define gc getchar()
    #define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    IL int getint()
    {
    	RG int xi=0;
    	RG char ch=gc;
    	bool f=0;
    	while(ch<'0'||ch>'9')ch=='-'?f=1:f,ch=gc;
    	while(ch>='0'&&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
    	return f?-xi:xi;
    }
    template<typename T>
    IL void pi(T k,char ch=0)
    {
    	if(k<0)k=-k,putchar('-');
    	if(k>=10)pi(k/10,0);
    	putchar(k%10+'0');
    	if(ch)putchar(ch);
    }
    const int MAXN=1e6+7;
    struct edge{
    	int v,nxt;
    }e[MAXN];
    int head[MAXN],cnt=-1,n,m;
    inline void add(int u,int v)
    {
    	e[++cnt]=(edge){v,head[u]};
    	head[u]=cnt;
    }
    int ideg[MAXN],odeg[MAXN];
    int degree[MAXN];
    int stk[MAXN],top=0;
    bool vis[MAXN];
    namespace subtask1{
    	void dfs(int p)
    	{
    		for(int &i=head[p];~i;i=e[i].nxt)
    		{
    			if(!vis[i])
    			{
    				vis[i]=vis[i^1]=1;
    				int tmp=i;
    				dfs(e[i].v);
    				stk[++top]=tmp;
    			}
    			if(i==-1)break;
    		}
    	}
    	int main()
    	{
    		n=gi,m=gi;
    		for(int i=1;i<=m;++i)
    			{
    				int u=gi,v=gi;
    				add(u,v),add(v,u);
    				++degree[u],++degree[v];
    			}
    		for(int i=1;i<=n;++i)if(degree[i]&1)return puts("NO"),0;
    		for(int i=1;i<=n;++i)if(~head[i]){dfs(i);break;}
    		if(top!=m)return puts("NO"),0;
    		puts("YES");
    		for(int i=m;i;--i)
    			{
    				if((stk[i]&1)==1)putchar('-');
    				pi(stk[i]/2+1,' ');
    			}
    		return 0;
    	}
    }
    namespace subtask2{
    	inline void dfs(int p)
    	{
    		for(int &i=head[p];~i;i=e[i].nxt)
    		{
    			if(!vis[i])
    			{
    				vis[i]=1;
    				int tmp=i;
    				dfs(e[i].v);
    				stk[++top]=tmp;
    			}
    			if(i==-1)break;
    		}
    	}
    	int main()
    	{
    		n=gi,m=gi;
    		for(int i=1;i<=m;++i)
    		{
    			int u=gi,v=gi;
    			add(u,v);
    			++ideg[v],++odeg[u];
    		}
    		for(int i=1;i<=n;++i)if(ideg[i]^odeg[i])return puts("NO"),0;
    		for(int i=1;i<=n;++i)if(~head[i]){dfs(i);break;}
    		if(top!=m)return puts("NO"),0;
    		puts("YES");
    		for(int i=m;i;--i)pi(stk[i]+1,' ');
    		return 0;
    	}
    }
    int main(void)
    {
    	int t=gi;
    	memset(head,-1,sizeof head);
    	if(t==1)subtask1::main();
    	if(t==2)subtask2::main();
    	return 0;
    }
    

    咕咕咕

  • 相关阅读:
    异常详细信息: System.InvalidCastException: 对象不能从 DBNull 转换为其他类型——的解决方法
    .net显示今天农历的代码!
    在GridView中设置日期格式
    安装VS 2008 SP1后,智能提示变为英文的补丁发布
    SQL server无法执行查询,因为一些文件丢失或未注册等问题的解决
    SQL Server 2000企业管理器中MMC无法创建管理单元的解决方法
    FILTER:progid:DXImageTransform.Microsoft.Gradient使用
    [jQuery] event.stopPropagation()报错
    得到系统当前的dpi设置值
    VS2008 当前不会命中断点,还没有为该文档加载任何符号
  • 原文地址:https://www.cnblogs.com/LLCSBlog/p/11235684.html
Copyright © 2020-2023  润新知