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

UVA 10054 The Necklace (无向图的欧拉回路)

时间:2016-04-18 22:28:26      阅读:269      评论:0      收藏:0      [点我收藏+]

标签:

题意:

  妹妹有一条项链,这条项链由许多珠子串在一起组成,珠子是彩色的,两个连续的珠子的交汇点颜色相同,也就是对于相邻的两个珠子来说,前一个珠子的末端颜色和后一个珠子的首端颜色相同。有一天,项链断了,珠子洒落了一地,到处都是,妹妹使出浑身解数把地板上能看到的珠子(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\n", ++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\n", ans[i], ans[i + 1]);
116         }
117         else
118             printf("some beads may be lost\n");
119         if(T)printf("\n");
120     }
121     return 0;
122 }

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

UVA 10054 The Necklace (无向图的欧拉回路)

标签:

原文地址:http://www.cnblogs.com/Ash-ly/p/5405904.html

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