hihor 学习日记:hiho一下 第五十一周 (欧拉图)

http://hihocoder.com/contest/hiho51/problem/1

思路:

可以把轮盘的转换成成一张图,图由 2 N 1 2^{N -1} 个点, 2 N 2^{N} 条边,因为数字的转换是在后面N-1个数字后面加上1或0,所以点代表的就是后面N-1个数,边代表形成的数字,‘
比如N=3时:
在这里插入图片描述
这样就转化成一个有向图,那么把边全走一遍,并且每条边只走一次,那么就是找这个图的欧拉回路,那么这个图存在不存在欧拉回路呢?
题目给出了解释
在这里插入图片描述
额,那根据给的伪代码,写出程序时,得出的结果是:
在这里插入图片描述
倒过来时
1 3 7 6 5 2 4 0
001 011 111 110 101 010 100 000
易见,可以拼接成一个01串

AC代码:

#include <bits/stdc++.h>

using namespace std;
#define LL long long
const int Mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const double eps = 0.00000001;
const int INF = 0x3f3f3f3f;

struct Edge{
    int v, nex, w;
}edge[maxn << 1];

int tot, head[maxn];
int path_size = 0;
int path[maxn], vis[maxn];

void init() {
    tot = 0;
    memset(head, -1, sizeof(head));
    memset(vis, 0, sizeof(vis));
}

void addEdge(int u, int v, int w) {
    edge[tot].v = v;
    edge[tot].w = w;
    edge[tot].nex = head[u];
    head[u] = tot ++;
}

void DFS(int u) {
    for (int i = head[u]; i + 1; i = edge[i].nex) {
        int v = edge[i].v;
        if(!vis[i]) {
            vis[i] = 1;
            DFS(v);
            path[path_size ++] = i;
        }
    }
}

int main()
{
    init();
    int N;
    cin >> N;
    N --;
    for (int i = 0; i < (1 << N); i ++) {
        if(((i << 1) & (1 << N))) {
            addEdge(i, (i << 1) ^ (1 << N), ((i << 1) ^ (1 << N)) << 1);
            addEdge(i, (i << 1) ^ (1 << N) ^ 1, (i << 1) ^ 1);
        }else {
            addEdge(i, i << 1, i << 1);
            addEdge(i, i << 1 | 1, i << 1 | 1);
        }
    }
    DFS(0);
    for (int i = 0; i < path_size - 1; i ++)
        cout << (path[i] & 1);
    cout << path[-- path_size];
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/85056146