Alien’s Necklace

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1526    Accepted Submission(s): 415

Problem Description
JYY is taking a trip to Mars. To get accepted by the Martians, he decided to make a magic necklace for their king. (Otherwise, JYY will be eaten) Now, he has collected many magic balls, and he is going to string them up.

Unfortunately, only particular pairs of balls can be adjacent in the necklace, otherwise they will explode. Notice that the first and the last ball in the necklace are also adjacent. Besides, the Martians think even numbers are unlucky, so the number of balls
in the necklace must be odd. (Of course each ball can be used only once)

A necklace contains at least 3 balls. Because the balls are really precious, JYY wants the necklace has as few balls as possible. (Then he can give rest balls to his GF)

So JYY wonders the number of balls he has to use to make this necklace.
 
Input
The input consists of several test cases. There is a single number above all, the number of cases. There are no more than 20 cases.

For each input, the first line contains 2 numbers N and M, N is the number of balls JYY collected, and M is the pairs of compatible balls. Balls are numbered from 1 to N. Followed M lines, each contains 2 numbers A and B, means that ball A and ball B are compatible.
For each case, 0 < N <= 1,000, 0 < M <= 20,000.
 
Output
If the gift can't be done, just print "Poor JYY." in a line, otherwise, print the minimal number of balls in the necklace. Use the format in the example.
 
Sample Input
  1. 2
  2. 5 6
  3. 1 2
  4. 2 4
  5. 1 3
  6. 3 5
  7. 4 3
  8. 4 5
  9. 2 1
  10. 1 2
 
Sample Output
  1. Case 1: JYY has to use 3 balls.
  2. Case 2: Poor JYY.
 

题意:让找到一个环使得组成环的点数为奇数且点数至少为3,。

由于一个点能够多个途径到达,但从一点出发第一次到达的肯定是最短路径,又题目要求的奇偶性,每次到达一个点步数的奇偶性进行标记。

  1. #include<stdio.h>
  2. #include<algorithm>
  3. #include<queue>
  4. #include<string.h>
  5. #include<vector>
  6. using namespace std;
  7. #define N 1005
  8. #define ll __int64
  9. const int inf=0x7fffffff;
  10. vector<int>g[N];
  11. int vis[N][2];
  12. struct node
  13. {
  14. int u,t;
  15. friend bool operator<(node a,node b)
  16. {
  17. return a.t>b.t;
  18. }
  19. };
  20. int bfs(int s)
  21. {
  22. int i,u,v;
  23. priority_queue<node >q;
  24. node cur,next;
  25. cur.u=s;
  26. cur.t=1;
  27. memset(vis,0,sizeof(vis));
  28. vis[s][1]=1; //奇数点。用一个珠子
  29. q.push(cur);
  30. while(!q.empty())
  31. {
  32. cur=q.top();
  33. q.pop();
  34. u=cur.u;
  35. for(i=0;i<g[u].size();i++)
  36. {
  37. next.u=v=g[u][i];
  38. next.t=cur.t+1;
  39. if(v==s&&next.t%2==0&&next.t>3) //结点处到达两次。故应该减一
  40. return next.t-1;
  41. if(!vis[v][next.t%2])
  42. {
  43. vis[v][next.t%2]=1;
  44. q.push(next);
  45. }
  46. }
  47. }
  48. return inf;
  49. }
  50. int main()
  51. {
  52. int i,n,m,u,v,tt,cnt=0;
  53. scanf("%d",&tt);
  54. while(tt--)
  55. {
  56. scanf("%d%d",&n,&m);
  57. for(i=1;i<=n;i++)
  58. g[i].clear();
  59. while(m--)
  60. {
  61. scanf("%d%d",&u,&v);
  62. g[u].push_back(v);
  63. g[v].push_back(u);
  64. }
  65. int ans=inf;
  66. for(i=1;i<=n;i++)
  67. ans=min(ans,bfs(i));
  68. if(ans==inf)
  69. printf("Case %d: Poor JYY.\n",++cnt);
  70. else
  71. printf("Case %d: JYY has to use %d balls.\n",++cnt,ans);
  72. }
  73. return 0;
  74. }

以下这样的方法是用一个数组记录到达该点的步数,当再次訪问该点时。说明出现环,直接推断奇偶性就能够了。

又要求所用珠子数目大于三,所以要用一个pre变量记录上一个节点的标号,推断是否是两点直接成环。

  1. #include<stdio.h>
  2. #include<algorithm>
  3. #include<queue>
  4. #include<string.h>
  5. #include<vector>
  6. using namespace std;
  7. #define N 1005
  8. #define ll __int64
  9. const int inf=0x7fffffff;
  10. vector<int>g[N];
  11. int vis[N][2];
  12. int ans;
  13. struct node
  14. {
  15. int u,t,pre;
  16. friend bool operator<(node a,node b)
  17. {
  18. return a.t>b.t;
  19. }
  20. };
  21. int bfs(int s)
  22. {
  23. int i,u,v,t;
  24. priority_queue<node >q;
  25. node cur,next;
  26. cur.u=s;
  27. cur.t=1;
  28. cur.pre=-1;
  29. memset(vis,0,sizeof(vis));
  30. vis[s][1]=1;
  31. q.push(cur);
  32. while(!q.empty())
  33. {
  34. cur=q.top();
  35. q.pop();
  36. u=cur.u;
  37. for(i=0;i<g[u].size();i++)
  38. {
  39. next.u=v=g[u][i];
  40. next.t=cur.t+1;
  41. next.pre=u;
  42. if(v==cur.pre)
  43. continue;
  44. if(vis[v][0]) //偶数点
  45. {
  46. t=cur.t+vis[v][0];
  47. if(t%2==0)
  48. return t-1;
  49. }
  50. else if(vis[v][1])
  51. {
  52. t=cur.t+vis[v][1];
  53. if(t%2==0)
  54. return t-1;
  55. }
  56. else
  57. {
  58. vis[v][next.t%2]=next.t;
  59. q.push(next);
  60. }
  61. }
  62. }
  63. return inf;
  64. }
  65. int main()
  66. {
  67. int i,n,m,u,v,tt,cnt=0;
  68. scanf("%d",&tt);
  69. while(tt--)
  70. {
  71. scanf("%d%d",&n,&m);
  72. for(i=1;i<=n;i++)
  73. g[i].clear();
  74. while(m--)
  75. {
  76. scanf("%d%d",&u,&v);
  77. g[u].push_back(v);
  78. g[v].push_back(u);
  79. }
  80. ans=inf;
  81. for(i=1;i<=n;i++)
  82. ans=min(ans,bfs(i));
  83. if(ans==inf)
  84. printf("Case %d: Poor JYY.\n",++cnt);
  85. else
  86. printf("Case %d: JYY has to use %d balls.\n",++cnt,ans);
  87. }
  88. return 0;
  89. }

hdu 1689 Alien’s Necklace (bfs层次图剪枝)的更多相关文章

  1. POJ3967Ideal Path[反向bfs 层次图]

    Ideal Path Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 1754   Accepted: 240 Descri ...

  2. hdu 1689 求奇环bfs关键是层次图

    #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> usin ...

  3. UVA 1599, POJ 3092 Ideal Path 理想路径 (逆向BFS跑层次图)

    大体思路是从终点反向做一次BFS得到一个层次图,然后从起点开始依次向更小的层跑,跑的时候选则字典序最小的,由于可能有多个满足条件的点,所以要把这层满足条件的点保存起来,在跑下一层.跑完一层就会得到这层 ...

  4. hdu 1044 BFS(压缩图)+DFS

    题意:              给你起点,终点,图上有墙有路还有宝物,问你在规定时间内能否能到终点,如果能问最多能捡到多少宝物. 思路:           看完这个题目果断 BFS+三维的mark ...

  5. 使用Architecture Explorer分析应用程序及使用层次图

    使用Architecture Explorer分析应用程序 Architecture Explorer和依赖图可以帮助我们了解所有的项目,包括小项目和大项目.Architecture Explorer ...

  6. HDU 2717 Catch That Cow --- BFS

    HDU 2717 题目大意:在x坐标上,农夫在n,牛在k.农夫每次可以移动到n-1, n+1, n*2的点.求最少到达k的步数. 思路:从起点开始,分别按x-1,x+1,2*x三个方向进行BFS,最先 ...

  7. UIKit框架类层次图

    学习UIKit应该首选了解UIKit类的层次图,从根类一层一层的拨.

  8. uva 10983 Buy one, get the rest free 二分判定层次图

    二分枚举租用飞机的最大花费,然后用小于等于最大花费的边构建层次图(依据时间) 构图思路:   利用二元组(x,y)表示 x天y城市 1. e天有飞机从a城市飞到b城市,能够承载x人,则添加单向边 ( ...

  9. HDU.1689 Just a Hook (线段树 区间替换 区间总和)

    HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...

随机推荐

  1. (33)zabbix proxy分布式监控配置

    概述 zabbix proxy可以代替zabbix server检索客户端的数据,然后把数据汇报给zabbix server,并且在一定程度上分担了zabbix server的压力.zabbix pr ...

  2. python入门(一)作业

    一,流程控制之if...else 1. 如果:女人的年龄>30岁,那么:叫阿姨,否则:叫小妞 age_of_girl = 21 if age_of_girl >30: print('阿姨' ...

  3. PHP方法之 mb_substr

    主要功能:中文字符串截取,解决substr中文截取问题,用法基本和substr相同,他可以指定编码. 函数原型:string mb_substr ( string $str , int $start  ...

  4. 【转发】【linux】【ftp】CentOS 7.0安装配置Vsftp服务器

    adduser -d /var/www/android -g ftp -s /sbin/nologin ftp2 一.配置防火墙,开启FTP服务器需要的端口 CentOS 7.0默认使用的是firew ...

  5. Python9-列表-day4

    列表list 列表是python中的基础数据类型之一,其他语言中也有类似于列表的数据类型,比如js中叫数组,他是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型比如: li = [‘a ...

  6. 【HIHOCODER 1323】回文字符串(区间DP)

    描述 给定一个字符串 S ,最少需要几次增删改操作可以把 S 变成一个回文字符串? 一次操作可以在任意位置插入一个字符,或者删除任意一个字符,或者把任意一个字符修改成任意其他字符. 输入 字符串 S. ...

  7. Android开发工具——Gradle知识汇总

    1.什么是构建工具 Eclipse大家都知道是一种IDE(集成开发环境),最初是用来做Java开发的,而Android是基于Java语言的,所以最初Google还是希望Android能在Eclipse ...

  8. .NET中常见的加解密方式

    在互联网普及的初期,人们更关注单纯的连接性,以不受任何限制地建立互联网为最终目的.正如事情都具有两面性,互联网的便捷性给人们带来了负面问题,计算机病毒的侵害.信息泄露.网络欺诈等利用互联网的犯罪行为日 ...

  9. IDEA避免JAVA文件自动引入import.*包

    Intellij Idea工具在java文件中怎么避免import java.utils.*这样的导入方式,不推崇导入*这样的做法!Editor->Code Style->Java-> ...

  10. OpennSSL之基本了解

    HTTPS是一种协议,等于HTTP+TLS(由于历史原因,SSL3.0之后就被TLS1.0替代了).openssl是一套开源工具集,主要有两个特性: 实现了ssl2,ssl3,TLSv1,TLSv1. ...