zoukankan      html  css  js  c++  java
  • Domino

    题目大意:这是一个多米诺骨游戏,这个游戏的规则就是一个连着一个,现在给出 N 个多米诺,每个多米诺两边都有一个编号,相邻的多米诺的编号要一致,当然多米诺是可以翻转的(翻转就加‘-’,不翻转是‘+’),输出一个多米诺的顺序,要从左往右。

    分析:开始的是有以为是二分匹配,然后发现并不能匹配,无法分成两个集合,网络流也不能搞,最后百度才知道是欧拉路径(从一点出发经过所有的路径,每条路只走一次),这个算法倒也不难理解,感觉很巧妙,如果点的入度都是偶数的话,那么就是欧拉回路(可以从一个点出发然后,最后还可以回到这个点结束),如果把所有的多米诺的编号当做节点,那么每个多米诺就是一条边,问题就转换成裸的欧拉路径题目了,判断是否是欧拉路径的时候需要注意,这个图是否是联通的。

    代码如下:

    ===================================================================================================

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 1007;
    
    struct Bridge
    {
        int u, v, next;
        int id, used;
    }edge[MAXN];
    int Head[MAXN], cnt;
    
    int ans[MAXN], na;
    
    void AddEdge(int u, int v, int id)
    {
        edge[cnt].u = u;
        edge[cnt].v = v;
        edge[cnt].id = id;
        edge[cnt].used = false;
        edge[cnt].next = Head[u];
        Head[u] = cnt++;
    
        swap(u, v);
    
        edge[cnt].u = u;
        edge[cnt].v = v;
        edge[cnt].id = id;
        edge[cnt].used = false;
        edge[cnt].next = Head[u];
        Head[u] = cnt++;
    }
    
    void DFS(int k)
    {
        for(int i=Head[k]; i!=-1; i=edge[i].next)
        {
            if(edge[i].used == false)
            {
                edge[i].used = edge[i^1].used = true;
                DFS(edge[i].v);
                ans[na++] = i;
            }
        }
    }
    
    int main()
    {
        int N, u, v;
    
        scanf("%d", &N);
    
        memset(Head, -1, sizeof(Head));
        cnt = 0, na=0;
    
        int ru[MAXN] = {0}, index=10;
    
        for(int i=1; i<=N; i++)
        {
            scanf("%d%d", &u, &v);
            AddEdge(u, v, i);
            ru[u]++, ru[v]++;
    
            index = u;
        }
    
        int sum = 0;
    
        for(int i=0; i<7; i++)
        {
            if(ru[i] % 2)
            {
                sum ++;
                index = i;
            }
        }
    
        if(sum != 2 && sum != 0)
            printf("No solution
    ");
        else
        {
            DFS(index);
    
            if(na != N)
                printf("No solution
    ");
            else
            {
                for(int i=0; i<na; i++)
                    printf("%d %c
    ", edge[ans[i]].id, ans[i]%2 ? '+' : '-');
            }
        }
    
        return 0;
    }
  • 相关阅读:
    jquery mobile
    可能用到的负边距应用
    兼容性问题
    less和scss
    函数的继承
    关于canvas
    html5表单属性
    html代码
    git 拉取远程分支 --本地分支不存在
    git 删除分支
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4803007.html
Copyright © 2011-2022 走看看