• SGU 101 Domino【欧拉路径】


    题目链接:

    http://acm.sgu.ru/problem.php?contest=0&problem=101

    题意:

    N个多米诺骨牌,每个骨牌左右两侧分别有一个0~6的整数(骨牌可以旋转以调换其左右两数),求一种把这些骨牌从左到右排列的方案,使得所有相邻的两数字相等(即左边骨牌右侧的数字等于右边骨牌左侧的数字)。

    分析:

    把数字当成点,骨牌当做边。构成无向图,求一发欧拉道路即可。
    无向图求欧拉路径还是很好写的。
    欧拉路径深入讲解:http://blog.chinaunix.net/uid-26380419-id-3164913.html

    代码:

    #include<iostream>
    #include<map>
    #include<cstring>
    #include<stack>
    #include<set>
    using namespace std;
    const int maxn = 200 + 5, maxm = 6 + 5;
    struct Edge{int to;int dir; int id;int next;};
    int tot = 0;
    Edge edge[maxn];
    stack<Edge>s;
    int pa[maxn], head[maxm], cnt[maxm];
    bool vis[maxn];
    int _find(int a)
    {
        if(a == pa[a]) return a;
        return pa[a] = _find(pa[a]);
    }
    void unite(int a, int b)
    {
        int ra = _find(a);
        int rb = _find(b);
        if(ra == rb) return ;
        pa[rb] = ra;
    }
    bool same(int a, int b)
    {
        return _find(a) == _find(b);
    }
    void add_edge(int u, int v, int id)
    {
        edge[tot].to = v;
        edge[tot].id = id;
        edge[tot].dir = 1;
        edge[tot].next = head[u];
        head[u] = tot++;
        edge[tot].to = u;
        edge[tot].dir = 0;
        edge[tot].id = id;
        edge[tot].next = head[v];
        head[v] = tot++;
    }
    void dfs(int u)
    {
        for(int i = head[u]; i != -1; i = edge[i].next){
            if(!vis[i]){
                vis[i] = true;
                vis[i^1] = true;
                dfs(edge[i].to);
                s.push(edge[i]);
            }
        }
    }
    int main (void)
    {
        int n ;cin>>n;
        memset(head, -1, sizeof(head));
        for(int i = 0; i <= 6; i++) pa[i] = i;
        int a, b;
        for(int i = 0; i < n; i++){
            cin>>a>>b;
            add_edge(a, b, i + 1);
            cnt[a]++;
            cnt[b]++;
            unite(a, b);
        }
        int be = -1;
        int ans = 0;
        for(int i = 0; i <= 6; i++){
            if(cnt[i] & 1){
                ans++;
                if(be == -1) be = i;
            }
        }
        if(ans != 0 && ans != 2) return cout<<"No solution"<<endl, 0;
        for(int i = 0; i <= 6; i++){
            if(cnt[i] &&  be == -1) be = i;
            if(cnt[i] && !same(i, be)){return cout<<"No solution"<<endl, 0;}
        }
        dfs(be);
        while(!s.empty()){
            Edge t = s.top();s.pop();
            cout<<t.id<<' ';
            if(t.dir == 0) cout<<"-"<<endl;
            else cout<<"+"<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    hash介绍
    序列化
    面向对象编程
    计算机系统基础知识05
    19、Python之队列
    18、Python之多线程
    17、Python之paramikomo
    16、Python之socket网络编程
    15、Python之异常处理
    14、Python之反射
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758657.html
Copyright © 2020-2023  润新知