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
2
5 6
1 2
2 4
1 3
3 5
4 3
4 5
2 1
1 2
 
Sample Output
Case 1: JYY has to use 3 balls.
Case 2: Poor JYY.
 

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

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

#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<vector>
using namespace std;
#define N 1005
#define ll __int64
const int inf=0x7fffffff;
vector<int>g[N];
int vis[N][2];
struct node
{
int u,t;
friend bool operator<(node a,node b)
{
return a.t>b.t;
}
};
int bfs(int s)
{
int i,u,v;
priority_queue<node >q;
node cur,next;
cur.u=s;
cur.t=1;
memset(vis,0,sizeof(vis));
vis[s][1]=1; //奇数点。用一个珠子
q.push(cur);
while(!q.empty())
{
cur=q.top();
q.pop();
u=cur.u;
for(i=0;i<g[u].size();i++)
{
next.u=v=g[u][i];
next.t=cur.t+1;
if(v==s&&next.t%2==0&&next.t>3) //结点处到达两次。故应该减一
return next.t-1;
if(!vis[v][next.t%2])
{
vis[v][next.t%2]=1;
q.push(next);
}
}
}
return inf;
}
int main()
{
int i,n,m,u,v,tt,cnt=0;
scanf("%d",&tt);
while(tt--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
g[i].clear();
while(m--)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
int ans=inf;
for(i=1;i<=n;i++)
ans=min(ans,bfs(i));
if(ans==inf)
printf("Case %d: Poor JYY.\n",++cnt);
else
printf("Case %d: JYY has to use %d balls.\n",++cnt,ans);
}
return 0;
}

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

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

#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<vector>
using namespace std;
#define N 1005
#define ll __int64
const int inf=0x7fffffff;
vector<int>g[N];
int vis[N][2];
int ans;
struct node
{
int u,t,pre;
friend bool operator<(node a,node b)
{
return a.t>b.t;
}
};
int bfs(int s)
{
int i,u,v,t;
priority_queue<node >q;
node cur,next;
cur.u=s;
cur.t=1;
cur.pre=-1;
memset(vis,0,sizeof(vis));
vis[s][1]=1;
q.push(cur);
while(!q.empty())
{
cur=q.top();
q.pop();
u=cur.u;
for(i=0;i<g[u].size();i++)
{
next.u=v=g[u][i];
next.t=cur.t+1;
next.pre=u;
if(v==cur.pre)
continue;
if(vis[v][0]) //偶数点
{
t=cur.t+vis[v][0];
if(t%2==0)
return t-1;
}
else if(vis[v][1])
{
t=cur.t+vis[v][1];
if(t%2==0)
return t-1;
}
else
{
vis[v][next.t%2]=next.t;
q.push(next);
}
}
}
return inf;
}
int main()
{
int i,n,m,u,v,tt,cnt=0;
scanf("%d",&tt);
while(tt--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
g[i].clear();
while(m--)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
ans=inf;
for(i=1;i<=n;i++)
ans=min(ans,bfs(i));
if(ans==inf)
printf("Case %d: Poor JYY.\n",++cnt);
else
printf("Case %d: JYY has to use %d balls.\n",++cnt,ans);
}
return 0;
}

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. verilog behavioral modeling --procedural assignments

    1.procedural assignments are used for updating reg ,integer , time ,real,realtime and memory data ty ...

  2. 我的Python分析成长之路11

    数据预处理 如何对数据进行预处理,提高数据质量,是数据分析中重要的问题. 1.数据合并 堆叠合并数据,堆叠就是简单地把两个表拼在一起,也被称为轴向链接,绑定或连接.依照轴的方向,数据堆叠可分为横向堆叠 ...

  3. Java-获取Class对象的名称

    package com.tj; public class MyClass2 { public static void main(String[] args) { Class cls = java.la ...

  4. mysql无法创建外键问题

    在阿里云上面安装配置了Mysql后,无法创建外键, 原因及解决方法: 选择InnoDB引擎,因为MyISAM引擎不支持外键,默默地说一句,MySQL真神奇

  5. A. Nearest Common Ancestors

    A. Nearest Common Ancestors Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 10000KB   64-bi ...

  6. 每天一个linux命令目录(转)

    一. 文件目录操作命令: 1.每天一个linux命令(1):ls命令 2.每天一个linux命令(2):cd命令  3.每天一个linux命令(3):pwd命令 4.每天一个linux命令(4):mk ...

  7. [luoguP2805] [NOI2009]植物大战僵尸(网络流)

    传送门 结论:这是最大权闭合图的模型 因为可能A保护B,B保护A,出现环. 所以由植物A向植物A保护的植物连边,然后拓扑排序,将环去掉. 然后将拓扑排序的边反向连,建立最大权闭合图的模型. 跑最大流( ...

  8. bzoj1225 [HNOI2001] 求正整数

    1225: [HNOI2001] 求正整数 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 762  Solved: 313[Submit][Statu ...

  9. 转载:CreateMutex WaitForSingleObject ReleaseMutex使用

    HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes,// BOOL bInitialOwner,  // flag for init ...

  10. 【bzoj2733】[HNOI2012]永无乡 线段树合并

    Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...