码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 11054 The Necklace 转化成欧拉回路

时间:2014-05-26 17:17:00      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:style   c   class   blog   code   java   

题意比较简单,给你n个项链碎片,每个碎片的两半各有一种颜色,最后要把这n个碎片串成一个项链,要求就是相邻碎片必须是同种颜色挨着。

看了下碎片总共有1000个,颜色有50种,瞬间觉得普通方法是无法在可控时间内做出来的,因为碎片到底放哪里以及是正着放还是反着放都是不可控的。

这个时候数学建模就真的好重要了,如果我们能把颜色作为节点,一个碎片就表示两个节点连了一条路,那其实就是走了一遍欧拉回路,就意味着项链做成了。

太叼了,这个思想真心不错。。。LRJ书上的提示,否则我还真是想不到可以这样。

 

不过还有个问题就是,欧拉回路用的DFS,按题目这个数据规模应该是会TLE的。

写上一句的时候突然灵感了一下,普通DFS是 状态^层数 为复杂度,这个看似层数特别多 假设有n条边,就应该要递归n层,就有50^n,,,但其实错了,欧拉回路走完所有的路就终止了,所以越到下面可选状态越少,最终还是最多1000个状态就可以了(即总路径条数)这也是为什么这个DFS不会TLE

bubuko.com,布布扣
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int mat[55][55];
int deep[55];
void init()
{
    memset(mat,0,sizeof mat);
    memset(deep,0,sizeof deep);
}
void euler(int u)
{
    for (int i=1;i<=50;i++){
        while (mat[u][i]){ //可能有多个同样的碎片,意味着两个节点有多条边
            mat[u][i]--;
            mat[i][u]--;
            euler(i);
            printf("%d %d\n",i,u);//dfs是反过来的,因此把孩子输出在前面,使得回路正确
        }
    }
}
int main()
{
    int t,n,a,b,kase=0;
    scanf("%d",&t);
    while (t--){
        init();
        scanf("%d",&n);
        for (int i=0;i<n;i++){
            scanf("%d%d",&a,&b);
            deep[a]++;deep[b]++;
            mat[a][b]++;mat[b][a]++;
        }
        printf("Case #%d\n",++kase);
        bool flag=0;
        for (int i=1;i<=50;i++){
            if (deep[i]%2==1){flag=1;break;}
        }
        if (flag){
            puts("some beads may be lost");
            if (t) puts("");
            continue;
        }
        int u=1;
        while (deep[u]==0) u++;
        euler(u);
        if (t) puts("");
    }
    return 0;
}
bubuko.com,布布扣

 

UVA 11054 The Necklace 转化成欧拉回路,布布扣,bubuko.com

UVA 11054 The Necklace 转化成欧拉回路

标签:style   c   class   blog   code   java   

原文地址:http://www.cnblogs.com/kkrisen/p/3752676.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!