[关闭]
@sensitive-cs 2019-01-30T07:31:24.000000Z 字数 1431 阅读 656

P-欧拉路 uva10054

题目大意:

有一串项链由若干个珠子构成,每两个珠子项链的一端颜色的相同的。

现在给出这些珠子两端的颜色,问用尽所有的珠子能否构成一串项链。

题目思路:

珠子的两端视作点,珠子本身视作边,那么就是从一个点出发遍历完所有的边并且回到起点,因为项链是一个环,所以最后拼接在一起,拼接处的颜色要相同。

那么这就是一个欧拉回路。

需要注意2个地方:

1.判断是否连通,这题的点的序号不一定是连续的;

2.欧拉回路输出路径,需要用到栈来存边,具体见紫书P169。

代码

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. #include <vector>
  5. #include <stack>
  6. using namespace std;
  7. typedef pair<int,int> pii;
  8. stack<pii> s;
  9. struct edge
  10. {
  11. int to;
  12. int id;
  13. edge(int a,int b)
  14. {
  15. to = a;
  16. id = b;
  17. }
  18. };
  19. int dg[55];
  20. vector<edge> G[55];
  21. bool vis[1005];
  22. void dfs(int u)
  23. {
  24. vis[u] = 1;
  25. for (auto x : G[u])
  26. {
  27. if (!vis[x.to])
  28. {
  29. dfs(x.to);
  30. }
  31. }
  32. }
  33. void euler(int u)
  34. {
  35. for (auto x : G[u])
  36. {
  37. int id = x.id;
  38. int to = x.to;
  39. if (!vis[id])
  40. {
  41. vis[id] = 1;
  42. euler(to);
  43. s.push(pii(u,to));
  44. }
  45. }
  46. }
  47. int main()
  48. {
  49. int T;
  50. int cas = 0;
  51. scanf("%d",&T);
  52. while (T--)
  53. {
  54. memset(dg,0,sizeof(dg));
  55. memset(vis,0,sizeof(vis));
  56. for (int i = 1;i <= 50;i++) G[i].clear();
  57. if (cas) puts("");
  58. printf("Case #%d\n",++cas);
  59. int n;
  60. scanf("%d",&n);
  61. int cnt = 0;
  62. for (int i = 0;i < n;i++)
  63. {
  64. int x,y;
  65. scanf("%d%d",&x,&y);
  66. if (!vis[x])
  67. {
  68. vis[x] = 1;
  69. cnt++;
  70. }
  71. if (!vis[y])
  72. {
  73. vis[y] = 1;
  74. cnt++;
  75. }
  76. dg[x]++;
  77. dg[y]++;
  78. G[x].push_back(edge(y,i));
  79. G[y].push_back(edge(x,i));
  80. }
  81. for (int i = 1;i <= 50;i++)
  82. {
  83. if (vis[i])
  84. {
  85. memset(vis,0,sizeof(vis));
  86. dfs(i);
  87. break;
  88. }
  89. }
  90. bool f = 0;
  91. int num = 0;
  92. for (int i = 1;i <= 50;i++)
  93. {
  94. if (vis[i]) num++;
  95. }
  96. if (num != cnt) f = 1;
  97. for (int i = 1;i <= 50;i++)
  98. {
  99. if (dg[i] % 2) f = 1;
  100. }
  101. if (f)
  102. {
  103. puts("some beads may be lost");
  104. continue;
  105. }
  106. memset(vis,0,sizeof(vis));
  107. for (int i = 1;i <= 50;i++)
  108. {
  109. if (dg[i])
  110. {
  111. euler(i);
  112. break;
  113. }
  114. }
  115. while (!s.empty())
  116. {
  117. auto x = s.top();
  118. s.pop();
  119. printf("%d %d\n",x.first,x.second);
  120. }
  121. }
  122. return 0;
  123. }
  124. /*
  125. 2
  126. 5
  127. 1 2
  128. 2 3
  129. 3 4
  130. 4 5
  131. 5 6
  132. 5
  133. 2 1
  134. 2 2
  135. 3 4
  136. 3 1
  137. 2 4
  138. */
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注