zoukankan      html  css  js  c++  java
  • UVA 10054 The Necklace (无向图的欧拉回路)

    本文链接:http://www.cnblogs.com/Ash-ly/p/5405904.html

    题意:

      妹妹有一条项链,这条项链由许多珠子串在一起组成,珠子是彩色的,两个连续的珠子的交汇点颜色相同,也就是对于相邻的两个珠子来说,前一个珠子的末端颜色和后一个珠子的首端颜色相同。有一天,项链断了,珠子洒落了一地,到处都是,妹妹使出浑身解数把地板上能看到的珠子(5-1000)都捡了起来,但是不确定是否收集齐了。给你他妹妹收集的珠子的两端的颜色编号(1 - 50),让你判断是否收集齐了。

    思路:

      把颜色看成点,把一个珠子看成一个无向边,则问题有解,当且仅当图中存在欧拉回路。于是先判断由题意构建出来的无向图是否存在欧拉回路,无向图能否构建出来欧拉回路需要满足两个条件:

    1:底图连通,可以用并查集或者DFS判断,这里利用并查集了。

    2:不存在度数为奇数的点。

      判断完成后,利用DFS遍历整个图,每访问一个点就把这个点压入栈中,回溯时弹出来当前点并记录下来。随后得到的就是欧拉回路的点的顺序,连续的两个点就是问题需要输出的边。

    代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <algorithm>
      7 #include <stack>
      8 #include <queue>
      9 using namespace std;
     10 
     11 const int maxV = 50;
     12 const int maxE = 1000;
     13 int degree[maxV + 7];
     14 int pre[maxV + 7];
     15 int head[maxV + 7];
     16 int vis[maxE * 2 + 7];
     17 int E, V;
     18 
     19 struct EdgeNode
     20 {
     21     int to;
     22     int next;
     23 }edges[2 * maxE + 7];
     24 
     25 void initPre()
     26 {
     27     for(int i = 1; i <= maxV; i++)pre[i] = i;
     28 }
     29 
     30 int Find(int x)
     31 {
     32     return x == pre[x] ? x : pre[x] = Find(pre[x]);
     33 }
     34 
     35 void mix(int x, int y)
     36 {
     37     int fx = Find(x);
     38     int fy = Find(y);
     39     if(fx != fy) pre[fx] = fy;
     40 }
     41 
     42 int isEuler()
     43 {
     44     for(int i = 1; i <= maxV; i++)
     45         if(degree[i] & 1) return 0;
     46     return 1;
     47 }
     48 
     49 int isConnct()
     50 {
     51     int cnt = 0;
     52     for(int i = 1; i <= maxV; i++)
     53         if(degree[i] && pre[i] == i) cnt++;
     54     if(cnt == 1) return 1;
     55     return 0;
     56 }
     57 
     58 stack<int> eu;
     59 int ans[maxE + 7];
     60 int len;
     61 void eulerDFS(int now)
     62 {
     63     eu.push(now);
     64     for(int k = head[now]; k != -1; k = edges[k].next)
     65     {
     66         if(!vis[k])
     67         {
     68             vis[k] = 1;
     69             if(k & 1) vis[k + 1] = 1;
     70             else vis[k - 1] = 1;
     71             eulerDFS(edges[k].to);
     72         }
     73     }
     74     ans[++len] = eu.top();//储存欧拉回路点的序列 
     75     eu.pop();
     76 }
     77 
     78 int main()
     79 {
     80     //freopen("in.txt", "r", stdin);
     81     int T;
     82     scanf("%d", &T);
     83     int kas = 0;
     84     while(T--)
     85     {
     86         scanf("%d", &E);
     87         memset(degree, 0, sizeof(degree));
     88         memset(edges, 0, sizeof(EdgeNode));
     89         memset(head, -1, sizeof(head));
     90         initPre();
     91         int st = 51;//默认路径起点 
     92         for(int i = 1; i <= E; i++)
     93         {
     94             int u, v;
     95             scanf("%d%d", &u, &v);
     96             edges[2 * i - 1].to = v;//链式前向星存储无向图的边需正反各存一次 
     97             edges[2 * i - 1].next = head[u];
     98             head[u] = 2 * i - 1;
     99             edges[2 * i].to = u;
    100             edges[2 * i].next = head[v];
    101             head[v] = 2 * i;
    102             degree[u]++;
    103             degree[v]++;
    104             mix(u, v);
    105             st = min(st, min(u, v));
    106         }
    107         printf("Case #%d
    ", ++kas);
    108         if(isConnct() && isEuler())
    109         {
    110             memset(vis, 0, sizeof(vis));
    111             memset(ans, 0, sizeof(ans));
    112             len = 0;
    113             eulerDFS(st);
    114             for(int i = 1; i < len; i++)//两个相邻的点构成一条边 
    115                 printf("%d %d
    ", ans[i], ans[i + 1]);
    116         }
    117         else
    118             printf("some beads may be lost
    ");
    119         if(T)printf("
    ");
    120     }
    121     return 0;
    122 }

     (PS:不只是题意没理解透还是什么,如果妹妹没捡起来的刚好也构成了欧拉回路,那么岂不是还是没收集齐嘛,不过等串起来应该会发现的 (逃......)

  • 相关阅读:
    cookie记住密码功能
    jquery 实现邮箱输入自动提示功能
    忘记密码功能的安全实现(邮件方式)
    java 实现从15位~18位的身份证号码转换,校验中国大陆公民身份证、香港居民身份证、澳门身份证和台湾身份证。
    myeclipse中发送邮件出现Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream
    几种任务调度的 Java 实现方法与比较
    CentOs中mysql的安装与配置
    CentOs下jdk的安装
    linux中vi编辑器的使用
    Linux文件结构及基本文件夹
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5405904.html
Copyright © 2011-2022 走看看