zoukankan      html  css  js  c++  java
  • 【欧拉回路】【Fleury算法】CDOJ1642 老当益壮, 宁移白首之心?

    题意: 构造一个01串,使得满足以下条件: 1. 环状(即首尾相连) 2. 每一位取值为0或1 3. 长度是2^n 4. 对于每个(2^n个)位置,从其开始沿逆时针方向的连续的n位01串(包括自己) 构成的数均不相同,即0到2^n−1中的数各出现一次 数据范围: 1<=n<=15

    欧拉回路 考虑用一条边表示一个数,那么题目要求就是无重复的遍历完所有边, 则这是一个欧拉图的问题。

    对于有公共点的两条边,第一个的后n-1位和第二个的前n-1相同。 这样将一条边的前n-1位和后n-1位作为点,连边,这样来表示它。 如:对于01101,我们可以从0110向1101建一条有向边表示01101. 于是所建图有2^(n-1)个点,和2^n条边。 对于任一两个点,如果它们的前n-2位和后n-2位相同,就连一条有向边, 这样所得到的图一定是欧拉图,因为每个点的入度和出度都是2,一定存在 欧拉回路。

    以下代码采取的Fleury算法未经优化,其实应该及时删去已经访问过的边,而非打上标记。这样的复杂度会变高。

    #include<cstdio>
    using namespace std;
    int n;
    int v[100010],next[100010],first[20010],e;
    void AddEdge(int U,int V){
    	v[++e]=V;
    	next[e]=first[U];
    	first[U]=e;
    }
    bool vis[100010];
    void dfs(int U,bool dep){
    	for(int i=first[U];i;i=next[i]){
    		if(!vis[i]){
    			vis[i]=1;
    			dfs(v[i],1);
    		}
    	}
    	if(dep){
    		printf("%d",U&1);
    	}
    }
    int main(){
    //	freopen("i.in","r",stdin);
    	scanf("%d",&n);
    	for(int i=0;i<(1<<(n-1));++i){
    		AddEdge(i,(i-(i&(1<<(n-2))))<<1);
    		AddEdge(i,(i-(i&(1<<(n-2))))<<1|1);
    	}
    	dfs(0,0);
    	puts("");
    	return 0;
    }
  • 相关阅读:
    HashMap
    Java内部类应用——静态内部类
    transient关键字和@Transient 注解
    java基本数据类型传递与引用传递区别
    抽象类
    java collection-list详解
    Arrays,ArrayList,以及ArrayList源码分析
    【转载】【剑指offer】面试题40:最小的 k 个数中的优先级队列
    java stack总结
    java Queue
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6910405.html
Copyright © 2011-2022 走看看